Practical Bazel: Use a Single .bazelrc With Multiple Configurations
Practical Bazel bazel
Published: 2022-10-17
Practical Bazel: Use a Single .bazelrc With Multiple Configurations

Bazel users commonly need to manage multiple different configurations when building and testing software, such as:

  • A configuration that is used by developers on their own PCs, which often has debug mode turned on
  • A configuration that is used by the continuous integration (CI) default build and test pipeline, which often builds in release mode
  • A configuration for generating a tagged, version release, which often has stamping enabled
  • (Perhaps many more)

Each of these configurations often require a different combination of bazel command-line switches. Rather than trying to remember the exact switches to use on the command line or encoding the switches in a separate build script like build.sh, it is better to use a .bazelrc file to define a set of build configurations with associated Bazel command-line switches.

Here’s a real-world example of a .bazelrc file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# A real-world .bazelrc
#
# NOTE: Setting action_env as below is probably a bad idea because it
# negatively affects build caching and reproducibility.  This decision
# was made by this project before we fully appreciated the "right way"
# of doing things in Bazel.  However, I am providing the .bazelrc as-is
# to illustrate what a real one might look like, warts and all.

# Any Jenkins build.  Run with --config=jenkins.
build:jenkins -c opt --remote_cache=http://localhost:8000 --experimental_convenience_symlinks=ignore --action_env=BRANCH_NAME --action_env=BUILD_NUMBER
test:jenkins -c opt --remote_cache=http://localhost:8000 --test_output=errors --keep_going --action_env=RUNNING_IN_JENKINS=1 --action_env=BRANCH_NAME --action_env=BUILD_NUMBER --experimental_convenience_symlinks=ignore
run:jenkins -c opt --remote_cache=http://localhost:8000 --experimental_convenience_symlinks=ignore --action_env=BRANCH_NAME --action_env=BUILD_NUMBER

# Jenkins master CI builds.  Run with --config=jenkins_master.
build:jenkins_master --config=jenkins
build:jenkins_master --stamp
build:jenkins_master --remote_upload_local_results=true
test:jenkins_master --config=jenkins
test:jenkins_master --remote_upload_local_results=true
run:jenkins_master --config=jenkins

# Jenkins nightly CI config.  Run with --config=jenkins_nightly
build:jenkins_nightly --config=jenkins
build:jenkins_nightly --stamp
test:jenkins_nightly --action_env=RUNNING_IN_JENKINS_NIGHTLY=1 --config=jenkins
test:jenkins_nightly --cache_test_results=no
run:jenkins_nightly --config=jenkisn

# Global options set on every build
build --cxxopt='-std=c++17'
# Use downloaded JDK 15 for all Java needs (replaces --javabase)
build --java_runtime_version=remotejdk_15
# Allow use of implementation_deps on cc_library
build --experimental_cc_implementation_deps
# Don't let environment variables like $PATH sneak into the build, which can
# cause massive cache misses when they change.
build --incompatible_strict_action_env
# Speed up all builds by not checking if output files have been modified.
build --noexperimental_check_output_files
# Generate metadata for all builds (but we will only stamp on master & nightly,
# or rules that explicitly require it)
build --workspace_status_command $PWD/tools/build_info.sh

# Allow developers to add repo-specific overrides in their own personal .bazelrc.user file.
# This should be the very last line in .bazelrc.
try-import %workspace%/.bazelrc.user