docs/versions/7.5.0/reference/be/make-variables.mdx
{% dynamic setvar source_file "src/main/java/com/google/devtools/build/docgen/templates/be/make-variables.vm" %} {% dynamic setvar version "7.5.0" %} {% dynamic setvar original_path "/reference/be/make-variables" %} {% include "_buttons.html" %}
<ul> <li><a href="#use">Use</a></li> <li><a href="#predefined_variables">Predefined variables</a></li> <li><a href="#predefined_genrule_variables">Predefined genrule variables</a></li> <li><a href="#predefined_label_variables">Predefined source/output path variables</a></li> <li><a href="#custom_variables">Custom variables</a></li> </ul> <p> "Make" variables are a special class of expandable string variables available to attributes marked as <i>"Subject to 'Make variable' substitution"</i>. </p> <p> These can be used, for example, to inject specific toolchain paths into user-constructed build actions. </p> <p> Bazel provides both <i>predefined</i> variables, which are available to all targets, and <i>custom</i> variables, which are defined in dependency targets and only available to targets that depend on them. </p> <p> The reason for the term "Make" is historical: the syntax and semantics of these variables were originally intended to match <a href="https://www.gnu.org/software/make/manual/html_node/Using-Variables.html">GNU Make</a>. </p> <h2 id="use">Use</h2> <p> Attributes marked as <i>"Subject to 'Make variable' substitution"</i> can reference the "Make" variable <code>FOO</code> as follows: </p> <p> <code>my_attr = "prefix $(FOO) suffix"</code> </p> <p> In other words, any substring matching <code>$(FOO)</code> gets expanded to <code>FOO</code>'s value. If that value is <code>"bar"</code>, the final string becomes: </p> <p> <code>my_attr = "prefix bar suffix"</code> </p> <p> If <code>FOO</code> doesn't correspond to a variable known to the consuming target, Bazel fails with an error. </p> <p> "Make" variables whose names are non-letter symbols, such as <code>@</code>, can also be referenced using only a dollar sign, without the parentheses. For example: </p> <p> <code>my_attr = "prefix $@ suffix"</code> </p> <p> To write <code>$</code> as a string literal (i.e. to prevent variable expansion), write <code>$$</code>. </p> <h2 id="predefined_variables">Predefined variables</h2> <p> Predefined "Make" variables can be referenced by any attribute marked as <i>"Subject to 'Make variable' substitution"</i> on any target. </p> <p> To see the list of these variables and their values for a given set of build options, run </p> <p><code>bazel info --show_make_env [build options]</code></p> <p> and look at the top output lines with capital letters. </p> <p><a href="https://github.com/bazelbuild/examples/tree/main/make-variables#predefined-variables"> See an example of predefined variables</a>.</p> <p><strong>Toolchain option variables</strong></p> <ul><!-- keep alphabetically sorted --> <li><code>COMPILATION_MODE</code>: <code>fastbuild</code>, <code>dbg</code>, or <code>opt</code>. (<a href="https://bazel.build/versions/7.5.0/docs/user-manual#flag--compilation_mode">more details</a>) </li> </ul> <p><strong>Path variables</strong></p> <ul><!-- keep alphabetically sorted --> <li> <p> <code>BINDIR</code>: The base of the generated binary tree for the target architecture. </p><p>
Note that a different tree may be used for programs that run during the
build on the host architecture, to support cross-compiling.
</p>
<p>
If you want to run a tool from within a <code>genrule</code>, the
recommended way to get its path is <code>$(<a
href="#predefined_label_variables">execpath</a> toolname)</code>,
where <i>toolname</i> must be listed in the <code>genrule</code>'s
<code><a
href="/versions/7.5.0/reference/be/general.html#genrule.tools">tools</a></code> attribute.
</p>
For source files, this is the path relative to your workspace root. For files that are outputs of rules, this is the file's <i>output path</i> (see the explanation of <i>output files</i> below).
</p> <p><a href="https://github.com/bazelbuild/examples/tree/main/make-variables#predefined-path-variables"> See an example of predefined path variables</a>.</p> <ul> <li> <p> <code>execpath</code>: Denotes the path beneath the <a href="/versions/7.5.0/docs/output_directories">execroot</a>
where Bazel runs build actions.
</p>
<p>
In the above example, Bazel runs all build actions in the directory linked
by the <code>bazel-myproject</code> symlink in your workspace root. The
source file <code>empty.source</code> is linked at the path
<code>bazel-myproject/testapp/empty.source</code>. So its exec path (which
is the subpath below the root) is <code>testapp/empty.source</code>. This
is the path build actions can use to find the file.
</p>
<p>
Output files are staged similarly, but are also prefixed with the subpath
<code>bazel-out/cpu-compilation_mode/bin</code> (or for the outputs of
tools: <code>bazel-out/cpu-opt-exec-hash/bin</code>). In the above example,
<code>//testapp:app</code> is a tool because it appears in
<code>show_app_output</code>'s <code><a
href="/versions/7.5.0/reference/be/general.html#genrule.tools">tools</a></code> attribute.
So its output file <code>app</code> is written to
<code>bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app</code>.
The exec path is thus <code>
bazel-out/cpu-opt-exec-hash/bin/testapp/app</code>. This extra prefix
makes it possible to build the same target for, say, two different CPUs in
the same build without the results clobbering each other.
</p>
<p>
The label passed to this variable must represent exactly one file. For
labels representing source files, this is automatically true. For labels
representing rules, the rule must generate exactly one output. If this is
false or the label is malformed, the build fails with an error.
</p>