As developers know, virtually all compilers support the notion
of compilation mode, e.g.. whether to compile the code in debug
or release mode. In Bazel, this concept is built natively into
the build system itself. When compiling software using bazel build,
one can select a compilation mode using the --compilation_mode
(often shorted to -c) flag.
The compilation modes supported by Bazel are:
fastbuildmeans build as fast as possible: generate minimal debugging information (e.g. ingcc, build with-gmlt -Wl,-S), and don’t optimize. This is the default.dbgmeans build with debugging enabled (e.g. ingcc, build with-g), so that you can use a debugger such asgdboptmeans build with optimization enabled and withassert()calls disabled (e.g. ingcc, build with-O2 -DNDEBUG).
These compilation modes can and should be respected by all custom rules so
that a Bazel user can use a single bazel build -c command to compile any
software in either fastbuild, dbg, or opt mode. In addition, a rule
author can also implement an optional compilation mode attribute which can
be used to override the mode on an individual target.
Here’s how to do so.
First, start with a basic build rule:
# foo_binary: A build rule which compiles code in a hypothetical
# language "foo" into a binary
def _impl(ctx):
# Rule implementation goes here
foo_binary = rule(
attrs = { ... },
implementation = _impl,
...
)
Next, add an attribute to the rule which a user can optionally set to set the compilation mode on a particular target:
foo_binary = rule(
attrs = {
"compilation_mode": attr.string(
mandatory = False,
values = ["dbg", "opt", "fastbuild"],
doc = "The compilation mode to use for this target. If not set, infer from --compilation_mode.",
),
}
)
Next, in the rule implementation, determine the effective compilation mode as follows:
def _impl(ctx):
# Determine the actual build configuration from the combination of
# ctx.attr.compilation_mode and --compilation_mode
if ctx.attr.compilation_mode:
compilation_mode = ctx.attr.compilation_mode
else:
compilation_mode = ctx.var["COMPILATION_MODE"]
# compilation_mode is one of dbg, opt, or fastbuild
A user of the rule can either specify the compilation mode on an individual target as follows:
foo_binary(
name = "...",
...,
# Always compile this target in optimized mode regardless of the
# bazel build -c option
compilation_mode = "opt",
)
Alternatively, they can affect all targets globally with the build -c option,
as in bazel build -c opt //....