#if (!$singlePage) --- layout: documentation title: Make Variables --- #end #if (!$singlePage) #parse("com/google/devtools/build/docgen/templates/be/header.vm") #end
This section describes how to use a special class of built-in string variables that are called the "Make" environment. Defining custom "Make" variables is not supported.
(The reason for the term "Make" is historical: the syntax and semantics of these variables are somewhat similar to those of GNU Make.)
To see the list of all common "Make" variables and their values,
run bazel info --show_make_env
.
Build rules can introduce additional rule specific variables. One example is
the cmd
attribute of a genrule.
Variables can be referenced in attributes
using $(FOO)
where FOO
is
the variable name. In the attribute documentation of rules, it is mentioned
when an attribute is subject to "Make" variable substitution. For those
attributes this means that any substrings of the form $(X)
within those attributes will be interpreted as references to the "Make"
variable X, and will be replaced by the appropriate value of that
variable for the applicable build configuration. The parens may be omitted
for variables whose name is a single character.
It is an error if such attributes contain embedded strings of the
form $(X)
where X is not the name of a
"Make" variable, or unclosed references such as $(
not
matched by a corresponding )
.
Within such attributes, literal dollar signs must be escaped
as $$
to prevent this expansion.
Those attributes that are subject to this substitution are explicitly indicated as such in their definitions in this document.
Bazel defines a set of "Make" variables for you.
The build system also provides a consistent PATH environment variable for genrules and tests which need to execute shell commands. For genrules, you can indirect your commands using the "Make" variables below. For basic Unix utilities, prefer relying on the PATH environment variable to guarantee correct results. For genrules involving compiler and platform invocation, you must use the "Make" variable syntax. The same basic command set is also available during tests. Simply rely on the PATH.
Compiler and Platforms available to genrules
These tools may not be in the PATH, therefore you must use "Make" variable syntax in your genrule's cmd attribute.CC
: The C and C++ compiler command. The built-in C++
rules are much more sophisticated than "run the compiler on it". In order to
support compilation modes as diverse as *SAN, ThinLTO, with/without
modules, and carefully optimized binaries at the same time as fast running
tests on multiple platforms, the built-in rules go to great lengths to
ensure the correct inputs, outputs, and command-line flags are set on each
of potentially multiple internally generated actions.
These environment variables are a fallback mechanism to be used by language experts in rare cases. If you are tempted to use them, please talk to us first.
It is strongly recommended to always use CC_FLAGS
in
combination with CC
. Fail to do so at your own risk.
C_COMPILER
:
The C/C++ compiler identifier, e.g. "llvm".
JAVA
: The "java" command (a Java virtual
machine). Avoid this, and use a java_binary
rule instead where
possible. May be a relative path. If you must change
directories before invoking java
, you need to capture the
working directory before changing it. This variable is only available if the
Java runtime, that is,
@bazel_tools//tools/jdk:current_java_runtime
or its host version (current_host_java_runtime
) is in the
toolchains
attribute.
STRIP
: The strip command from the same suite as the C/C++
compiler.AR
: The "ar" command from crosstool. NM
: The "nm" command from crosstool. OBJCOPY
: The objcopy command from the same suite as the C/C++
compiler. Tool option Variables
CC_FLAGS
: A minimal set of flags for the C/C++
compiler to be used by genrules. In particular, it contains flags to select
the correct architecture if CC
supports multiple architectures.
COMPILATION_MODE
: "fastbuild", "dbg", or "opt".Path Variables
BINDIR
: The base of the generated binary tree for the target
architecture. (Note that a different tree may be used for
programs that run during the build on the host architecture,
to support cross-compiling. If you want to run a tool from
within a genrule, the recommended way of specifying the path to
the tool is to use $(location toolname)
,
where toolname must be listed in the tools
attribute for the genrule.GENDIR
: The base of the generated code
tree for the target architecture.JAVABASE
: for Java, most of the tools in the
JDK should not be used as-is. The built-in Java rules use much more
sophisticated approaches to Java compilation and packaging than the upstream
tools can express, such as interface Jars, header interface Jars, and highly
optimized Jar packaging and merging implementations.
The base directory containing the Java utilities. May be a relative path. It will have a "bin" subdirectory.
This variable is only available if the Java runtime, that is,
@bazel_tools//tools/jdk:current_java_runtime
or its host version (current_host_java_runtime
) is in the
toolchains
attribute.
Architecture Variables
ABI
:
The C++ ABI version. TARGET_CPU
: The target architecture's cpu,
e.g. "piii" or "k8". Other Variables available to the cmd attribute of a genrule
OUTS
: The outs
list. If you have only one output
file, you can also use $@
.SRCS
: The srcs
list (or more
precisely, the pathnames of the files corresponding to
labels in the srcs
list). If you have only one
source file, you can also use $<
.<
: srcs
, if it is a single file.@
: outs
, if it is a single file.@D
: The output directory. If there is only
one filename in outs
, this expands to the
directory containing that file. If there are multiple
filenames, this variable instead expands to the package's root
directory in the genfiles
tree, even if all
the generated files belong to the same subdirectory!
If the genrule needs to generate temporary intermediate files
(perhaps as a result of using some other tool like a compiler)
then it should attempt to write the temporary files to
@D
(although /tmp
will also be
writable), and to remove any such generated temporary files.
Especially, avoid writing to directories containing inputs -
they may be on read-only filesystems, and even if they aren't,
doing so would trash the source tree.
In attributes that support it, all occurrences of
$(location label)
are replaced by the path to the
file denoted by label. Use location
if the label
outputs exactly one filename. This allows bazel to perform a check and give
an error if no or more than one files are represented by the given label; a
label referring to a source file always represents a single file, but a label
referring to a rule refers to all output files of that rule. Otherwise use
$(locations label)
; bazel will then raise an error
if no files are generated. In both cases, if the label is malformed then an
error is raised.
The label needs not be in canonical form:
foo
, :foo
and //somepkg:foo
are
all fine. It may also be the name of an output file from the
outs
attribute.
The expanded paths are relative to the runfiles directory of the
*_test
or *_binary
rule.