Bazel BUILD Encyclopedia of Functions

Contents

Concepts and terminology

Rules

LanguageBinary rulesLibrary rulesTest rulesOther rules
Android android_binary android_library android_test android_device android_manifest_merge
android_resources
Java java_binary java_import
java_library
java_test java_plugin
java_wrap_cc
Shell sh_binary sh_library sh_test
 
Rules that do not apply to a specific programming language
General filegroup test_suite genrule

Common definitions

This section defines various terms and concepts that are common to many functions or build rules below.

Bourne shell tokenization

Certain string attributes of some rules are split into multiple words according to the tokenization rules of the Bourne shell: unquoted spaces delimit separate words, and single- and double-quotes characters and backslashes are used to prevent tokenization.

Those attributes that are subject to this tokenization are explicitly indicated as such in their definitions in this document.

Attributes subject to "Make" variable expansion and Bourne shell tokenization are typically used for passing arbitrary options to compilers and other tools, such as the copts attribute of cc_library, or the javacopts attribute of java_library. Together these substitutions allow a single string variable to expand into a configuration-specific list of option words.

Label expansion

Some string attributes of a very few rules are subject to label expansion: if those strings contain a valid build label as a substring, such as //mypkg:target, and that label is a declared prerequisite of the current rule, it is expanded into the pathname of the file represented by the target //mypkg:target.

Example attributes include the cmd attribute of genrule, and the linkopts attribute of cc_library. The details may vary significantly in each case, over such issues as: whether relative labels are expanded; how labels that expand to multiple files are treated, etc. Consult the rule attribute documentation for specifics.

Attributes common to all build rules

This section describes attributes that are common to all build rules.
Please note that it is an error to list the same label twice in a list of labels attribute.

Attributes common to all test rules (*_test)

This section describes attributes that are common to all test rules.

Attributes common to all binary rules (*_binary)

This section describes attributes that are common to all binary rules.

Implicit output targets

When you define a build rule in a BUILD file, you are explicitly declaring a new, named rule target in a package. Many build rule functions also implicitly entail one or more output file targets, whose contents and meaning are rule-specific. For example, when you explicitly declare a java_binary(name='foo', ...) rule, you are also implicitly declaring an output file target foo_deploy.jar as a member of the same package. (This particular target is a self-contained Java archive suitable for deployment.)

Implicit output targets are first-class members of the build target graph. Just like other targets, they are built on demand, either when specified in the top-level built command, or when they are necessary prerequisites for other build targets. They can be referenced as dependencies in BUILD files, and can be observed in the output of analysis tools such as bazel query.

For each kind of build rule, the rule's documentation contains a special section detailing the names and contents of any implicit outputs entailed by a declaration of that kind of rule.

Please note an important but somewhat subtle distinction between the two namespaces used by the build system. Build labels identify targets, which may be rules or files, and file targets may be divided into either source (or input) file targets and derived (or output) file targets. These are the things you can mention in BUILD files, build from the command-line, or examine using bazel query; this is the target namespace. Each file target corresponds to one actual file on disk (the "file system namespace"); each rule target may correspond to zero, one or more actual files on disk. There may be files on disk that have no corresponding target; for example, .o object files produced during C++ compilation cannot be referenced from within BUILD files or from the command line. In this way, the build tool may hide certain implementation details of how it does its job. This is explained more fully in the BUILD Concept Reference.

*_binary

A *_binary rule compiles an application. This might be an executable, a .jar file, and/or a collection of scripts.

android_binary

android_binary(name, deps, srcs, resources, aaptopts, debug_key, deprecation, dexopts, distribs, licenses, obsolete, proguard_generate_mapping, proguard_specs, strict_android_deps, tags, testonly, visibility)

Produces Android application package files (.apk).

Implicit output targets

Arguments

java_binary

java_binary(name, deps, srcs, data, resources, args, classpath_resources, create_executable, deploy_env, deploy_manifest_lines, deprecation, distribs, javacopts, jvm_flags, launcher, licenses, main_class, obsolete, output_licenses, plugins, runtime_deps, stamp, swigdeps, tags, testonly, use_testrunner, visibility)

Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. The wrapper shell script uses a classpath that includes, among other things, a jar file for each library on which the binary depends.

Implicit output targets

Arguments

sh_binary

sh_binary(name, deps, srcs, data, args, bash_version, deprecation, distribs, licenses, obsolete, output_licenses, random_tmpdir, tags, testonly, visibility)

The sh_binary rule is used to declare executable programs in interpreted languages such as the Bourne shell, or Bash, Perl, Ruby, etc. (sh_binary is a double misnomer: its outputs aren't necessarily either shell programs or binary.) This rule ensures that all dependencies are built, and appear in the runfiles area at execution time. We recommend that you name your sh_binary() rules after the name of the script minus the extension (e.g. .sh); do not give the rule and the file the same name.

Implicit output targets

Arguments

Example

For a simple shell script with no dependencies or data:

sh_binary(
    name = "foo",
    srcs = ["foo.sh"],
)

*_library

A *_library() rule compiles some sources into a library. In general, a language_library rule works like the corresponding language_binary rule, but doesn't generate something executable.

android_library

android_library(name, deps, srcs, data, resources, deprecation, distribs, idl_import_root, idl_parcelables, idl_srcs, licenses, neverlink, obsolete, plugins, proguard_specs, strict_android_deps, tags, testonly, visibility)

This rule compiles and archives its sources into a .jar file. The Android runtime library android.jar is implicitly put on the compilation class path.

Implicit output targets

Arguments

java_import

java_import(name, data, constraints, deprecation, distribs, exports, jars, licenses, neverlink, obsolete, srcjar, tags, testonly, visibility)

This rule allows the use of precompiled JAR files as libraries for java_library rules.

Arguments

java_library

java_library(name, deps, srcs, data, resources, constraints, deprecation, distribs, exported_plugins, exports, javacopts, licenses, neverlink, obsolete, plugins, runtime_deps, tags, testonly, visibility)

This rule compiles and links sources into a .jar file.

Implicit output targets

Arguments

sh_library

sh_library(name, deps, srcs, data, deprecation, distribs, licenses, obsolete, tags, testonly, visibility)

The main use for this rule is to aggregate together a logical "library" consisting of related scripts—programs in an interpreted language that does not require compilation or linking, such as the Bourne shell—and any data those programs need at run-time. Such "libraries" can then be used from the data attribute of one or more sh_binary rules.

Historically, a second use was to aggregate a collection of data files together, to ensure that they are available at runtime in the .runfiles area of one or more *_binary rules (not necessarily sh_binary). However, the filegroup() rule should be used now; it is intended to replace this use of sh_library.

In interpreted programming languages, there's not always a clear distinction between "code" and "data": after all, the program is just "data" from the interpreter's point of view. For this reason (and historical accident) this rule has three attributes which are all essentially equivalent: srcs, deps and data. The recommended usage of each attribute is mentioned below. The current implementation does not distinguish the elements of these lists. All three attributes accept rules, source files and derived files.

Arguments

Examples

sh_library(
    name = "aggregator",
    data = [
        ":aggregator_service_script",  # a sh_binary with srcs
        ":deploy_aggregator",  # another sh_binary with srcs
    ],
)

*_test

A *_test rule compiles a test. See Common attributes for tests for an explanation of the common attributes.

android_test

android_test(name, deps, srcs, data, resources, args, debug_key, deprecation, dexopts, distribs, flaky, licenses, local, obsolete, proguard_generate_mapping, proguard_specs, shard_count, size, strict_android_deps, tags, target_devices, testonly, timeout, visibility)

A android_test rule runs Android tests. By default, it will start an emulator, install the application under test along with the test binary and any other needed Android binaries and run the tests defined in the test package. An option to run the test on an existing device is available to target_devices users when running locally.

These tests require an Android device (virtual or physical) to run because they rely on Android libraries only available on the device.

Arguments

java_test

java_test(name, deps, srcs, data, resources, args, classpath_resources, create_executable, deploy_manifest_lines, deprecation, distribs, flaky, javacopts, jvm_flags, launcher, licenses, local, main_class, obsolete, plugins, runtime_deps, shard_count, size, stamp, swigdeps, tags, test_class, testonly, timeout, use_testrunner, visibility)

A java_test() rule compiles a Java test. A test is binary wrapper around your test code. The test runner's main method is invoked instead of the main class being compiled.

Implicit output targets

Arguments

See the section on java_binary() arguments, with the caveats that there is no main_class argument. It also supports all attributes common to all test rules (*_test). java_test has this extra argument:

sh_test

sh_test(name, deps, srcs, data, args, bash_version, deprecation, distribs, flaky, licenses, local, obsolete, shard_count, size, tags, testonly, timeout, visibility)

A sh_test() rule creates a test. A test is a wrapper around the tested code. If you're working with Perl and want to write a unit test, then sh_test() is the best approach (though Perl is not supported).

Arguments

See the section on sh_binary() for other arguments. Also see the attributes common to all test rules (*_test).

"Make" Variables

This section describes how to use or define a special class of string variables that are called the "Make" environment. Bazel defines a set of standard "Make" variables, and you can also define your own.

(The reason for the term "Make" is historical: the syntax and semantics of these variables are somewhat similar to those of GNU Make, and in the original implementation, were implemented by GNU Make. The scare-quotes are present because newer build tools support "Make" variables without being implemented using GNU Make; therefore it is important to read the specification below carefully to understand the differences.)

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.

"Make" variable substitution

Variables can be referenced in attributes and other variables using either $(FOO) or varref('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.

Predefined "Make" Variables

Bazel defines a set of "Make" variables for you.

The build system also provides a consistent PATH 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 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.

Bazel uses a tiny Unix distribution to guarantee consistent behavior of build and test steps which execute shell code across all build execution hosting environments but it does not enforce a pure chroot. As such, do not use hard coded paths, such as /usr/bin/foo. Binaries referenced in hardcoded paths are not hermetic and can lead to unexpected and non-reproducible build behavior.

Command Variables for genrules

Note that in general, you should simply refer to many common utilities as bare commands that the $PATH variable will correctly resolve to hermetic versions for you.

Path Variables

Architecture Variables

Other Variables available to the cmd attribute of a genrule

Defining Your Own Variables

You may want to use Python-style variable assignments rather than "Make" variables, because they work in more use cases and are less surprising. "Make" variables will work in the cmd attribute of genrules and in the key of the abi_deps attribute of a limited number of rules, but only in very few other places.

To define your "Make" own variables, first call vardef() to define your variable, then call varref(name) to retrieve it. varref can be embedded as part of a larger string. Custom "Make" variables differ from ordinary "Python" variables in the BUILD language in two important ways:

vardef()

vardef(name, value, platform)

Define a variable for use within this BUILD file only. This variable can then be used by varref(). The value of the variable can be overridden on the command line by using the --define flag.

Arguments

Notes

Because references to "Make" variables are expanded after BUILD file evaluation, the relative order of vardef statements and rule declarations is unimportant; it is order of vardef statements relative to each other, and hence the state of the "Make" environment at the end of evaluation that matters.

If there are multiple matching vardef definitions for the same variable, the definition that wins is the last matching definition that specifies a platform, unless there are no matching definitions that specify a platform, in which case the definition that wins is the last definition without a platform.

varref

varref(name)

varref("FOO") is equivalent of writing "$(FOO)". It is used to dereference variables defined with vardef as well as predefined variables.

In rule attributes that are subject to "Make" variable substitution, the string produced by varref(name) will expand to the value of variable name.

varref(name) may not be used in rule attributes that are not subject to "Make" variable substitution.

Arguments

Notes

Examples

See vardef() examples.

Other Stuff

filegroup

filegroup(name, srcs, data, deprecation, distribs, licenses, obsolete, output_licenses, path, tags, testonly, visibility)

Use filegroup to give a convenient name to a collection of targets. These can then be referenced from other rules, e.g. the srcs attribute of a genrule, or the data attribute of a *_binary rule.

Motivation: this mechanism aims to replace the practice of referencing directory names as data dependencies. Referencing directory names is unsound as the build system does not have full knowledge of all files below the directory, so it may or may not rebuild as these files change. When combined with glob, filegroup can ensure that all files are explicitly known to the build system.

Arguments

Examples

To create a filegroup consisting of two source files, do

filegroup(
    name = "mygroup",
    srcs = [
        "a_file.txt",
        "another_file.txt",
    ],
)

Or, use a glob to grovel a testdata directory:

filegroup(
    name = "exported_testdata",
    srcs = glob([
        "testdata/*.dat",
        "testdata/logs/*.log",
    ]),
)

To make use of these definitions, reference the filegroup with a label from any rule:

cc_library(
    name = "my_library",
    srcs = ["foo.cc"],
    data = [
        "//my_package:exported_testdata",
        "//my_package:mygroup",
    ],
)

test_suite

test_suite(name, deprecation, distribs, licenses, obsolete, tags, testonly, tests, visibility)

A test_suite defines a set of tests that are considered "useful" to humans. This allows projects to define sets of tests, such as "tests you must run before checkin", "our project's stress tests" or "all small tests."

Arguments

android_device

android_device(name, cache, default_properties, deprecation, distribs, horizontal_resolution, licenses, obsolete, ram, screen_density, system_image, tags, testonly, vertical_resolution, visibility, vm_heap)

This rule creates an android emulator configured with the given specifications. This emulator may be started via a bazel run command or by executing the generated script directly.

Implicit output targets

Arguments

android_manifest_merge

android_manifest_merge(name, deps, srcs, deprecation, distribs, exclude_permissions, licenses, obsolete, tags, testonly, visibility)

This rule merges an AndroidManifest.xml file with other android manifests that your app depends on (mergees). Other manifests might come from android libraries that your project depends on (e.g.: userfeedback library), or on your test manifest used to produce test version of your app's binary. Optionally, permissions from the mergees can be excluded.

Implicit output targets

Arguments

android_resources

android_resources(name, resources, assets, assets_dir, custom_package, deprecation, distribs, exports_manifest, inline_constants, licenses, manifest, obsolete, rename_manifest_package, tags, testonly, visibility)

Generates name.srcjar which contains R.java, Manifest.java and any other java resources generated by aapt.

Implicit output targets

Arguments

Examples

Please see examples under android_binary.

Here is an example of combining multiple assets sources. Let //java/android/o/BUILD contain

exports_files(["assets/other"])

Then in the other package you can say:

android_resources(
    name = "r",
    assets = [
        "assets/source",
        "//java/android/o:assets/other",
    ],
    assets_dir = "assets",
    manifest = "AndroidManifest.xml",
)
android_resources(
    name = "r",
    assets = glob(["assets/**"])
    assets_dir = "moreassets",
    manifest = "AndroidManifest.xml",
)

genrule

genrule(name, srcs, outs, cmd, deprecation, distribs, executable, heuristic_label_expansion, licenses, local, message, obsolete, output_licenses, output_to_bindir, stamp, tags, testonly, tools, visibility)

A genrule generates one or more files, where the generation of those files is done with custom shell commands running in bash. While this makes them very flexible, they are also difficult to use correctly.

When not to use a genrule?

Cross-compilation Considerations

While genrules run during a build, their outputs are often used after the build, for deployment or testing. The build system uses the host configuration to describe the machines on which the build runs, and the target configuration to describe the machines on which the output of the build is supposed to run. It provides options to configure each of these, and it segregates the corresponding files into separate directories to avoid conflicts.

For genrules, the build system ensures that dependencies are built appropriately - srcs are built (if necessary) for the target configuration, tools are built for the host configuration, and the output is considered to be for the target configuration. It also provides "Make" variable that genrule commands can pass to the corresponding tools.

It is intentional that genrule does not have a deps attribute - other built-in rules use language-dependent meta information passed between the rules to automatically determine how to handle dependent rules, but this level of automation is not possible for genrules. Genrules work purely at the file and runfiles level.

Special Cases

Host-host compilation - in some cases, the build system needs to run genrules such that the output can also be run during the build. In that case, the build system automatically builds the srcs and outs for the host configuration, and sets the variables accordingly.

Genrule Environment

Genrules are executed in a sandbox that only allows access to declared inputs. Genrules that are run locally are currently an exception, but this may change in the future, i.e., local genrules will also be run in a sandbox. The declared output files from a genrule are copied out of the sandbox, whereas all other files are dropped.

Furthermore, the build system sets environment variables it sets PATH to point to a set of standard utilities). At least awk, bash, echo, diff, find, grep, gzip, m4, md5sum, patch, perl, sed, tar, and xargs are provided. It sets LANG to en_US. No other environment variables are set; in particular, no environment variables are passed through from the build system invocation.

The genrule command is executed in a bash shell. The bash shell is configured to fail when a command fails (set -e); at some point in the future, it will also fail when a command in a pipline fails (set -o pipefail). Genrules should not access the network (except to create connections between processes running within the same genrule on the same machine), though this is not currently enforced in all cases.

The build system automatically deletes any existing output files, but creates any necessary parent directories before it runs a genrule. It also removes any output files in case of a failure.

General Advice

Arguments

Examples

The following example shows how to process

genrule(
    name = "concat_all_files",
    srcs = [
        "//some:file",
        "//other:file",
    ],
    outs = ["concatenated.txt"],
    cmd = "cat $(location //some:file) $(location //other:file) > $@"
)

java_plugin

java_plugin(name, deps, srcs, data, resources, deprecation, distribs, generates_api, javacopts, licenses, neverlink, obsolete, plugins, processor_class, tags, testonly, visibility)

java_plugin() defines plugins for the Java compiler run by Bazel. At the moment, the only supported kind of plugins are annotation processors. A java_library or java_binary rule can run plugins by depending on them via the plugins attribute. A java_library can also export plugins automatically to libraries that directly depend on it using exported_plugins.

Implicit output targets

Arguments

Arguments are identical to java_library(), except for the addition of the processor_class argument.

java_wrap_cc

java_wrap_cc(name, deps, srcs, data, copts, deprecation, distribs, javacopts, legacy_override_module, licenses, obsolete, package, plugins, swig_includes, swig_top, tags, testonly, visibility)

java_wrap_cc() turns a .swig file and some C++ libraries into a Java swigging. The outputs are a static archive file and a Java archive that provides the Java interface. The archive file is linked into the swigdeps.so shared library, or if using a java launcher, linked into the launcher itself.

Implicit output targets

Arguments

package

This function declares metadata that applies to every subsequent rule in the package.

The package function is used at most once within a build package (BUILD file). It is recommended that the package function is called at the top of the file, before any rule.

Arguments

Examples

The declaration below declares that the rules in this package are visible only to members of package group //foo:target. Individual visibility declarations on a rule, if present, override this specification.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

This function defines a set of build packages. Package groups are used for visibility control. You can grant access to a rule to one or more package groups, every rule, or only to rules declared in the same package. For more detailed description of the visibility system, see the visibility attribute.

Arguments

Examples

The following package_group declaration specifies a package group called "tropical" that contains tropical fruits.
package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)
The following declarations specify the package groups of a fictional application:
package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

Description

# Description: ...

Each BUILD file should contain a Description comment.

Description comments may contain references to other documentation. A string that starts with "http" will become a link. HTML markup is allowed in description comments, but please keep the BUILD files readable. We encourage you to list the URLs of relevant design docs and howtos in these description comments.

distribs

distribs(distrib_methods)

distribs() specifies the default distribution method (or methods) of the build rules in a BUILD file. The distribs() directive should appear close to the beginning of the BUILD file, before any build rules, as it sets the BUILD-file scope default for build rule distribution methods.

Arguments

The argument, distrib_methods, is a list of distribution-method strings.

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() specifies a list of files belonging to this package that are exported to other packages but not otherwise mentioned in the BUILD file.

The BUILD file for a package may only refer to files belonging to another package if they are mentioned somewhere in the other packages's BUILD file, whether as an input to a rule or an explicit or implicit output from a rule. The remaining files are not associated with a specific rule but are just "data", and for these, exports_files ensures that they may be referenced by other packages. (One kind of data for which this is particularly useful are shell and Perl scripts.)

Note: A BUILD file only consisting of exports_files() statements is needless though, as there are no BUILD rules that could own any files. The files listed can already be accessed through the containing package and exported from there if needed.

Arguments

The argument is a list of names of files within the current package. A visibility declaration can also be specified; in this case, the files will be visible to the targets specified. If no visibility is specified, the files will be visible to every package, even if a package default visibility was specified in the package function. The licenses can also be specified.

glob

glob(include, exclude=[], exclude_directories=1)

Glob is a helper function that can be used anywhere a list of filenames is expected. It takes one or two lists of filename patterns containing the * wildcard: as per the Unix shell, this wildcard matches any string excluding the directory separator /. In addition filename patterns can contain the recursive ** wildcard. This wildcard will match zero or more complete path segments separated by the directory separator /. This wildcard can only be used as a complete path segment. For example, "x/**/*.java" is legal, but "test**/testdata.xml" and "**.java" are both illegal. No other wildcards are supported.

Glob returns a list of every file in the current build package that:

If the exclude_directories argument is enabled (1), files of type directory will be omitted from the results (default 1).

There are several important limitations and caveats:

  1. Globs only match files in your source tree, never generated files. If you are building a target that requires both source and generated files, create an explicit list of generated files, and use + to add it to the result of the glob() call.
  2. Globs may match files in subdirectories. And subdirectory names may be wildcarded. However...
  3. Labels are not allowed to cross the package boundary and glob does not match files in subpackages. For example, the glob expression **/*.cc in package x does not include x/y/z.cc if x/y exists as a package (either as x/y/BUILD, or somewhere else on the package-path). This means that the result of the glob expression actually depends on the existence of BUILD files — that is, the same glob expression would include x/y/z.cc if there was no package called x/y.
  4. The restriction above applies to all glob expressions, no matter which wildcards they use.

In general, you should try to provide an appropriate extension (e.g. *.html) instead of using a bare '*' for a glob pattern. The more explicit name is both self documenting and ensures that you don't accidentally match backup files, or emacs/vi/... auto-save files.

Glob Examples

Include all txt files in directory testdata except experimental.txt. Note that files in subdirectories of testdata will not be included. If you want those files to be included, use a recursive glob (**).

java_test(
    name = "myprog",
    srcs = ["myprog.java"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Recursive Glob Examples

Create a library built from all java files in this directory and all subdirectories except those whose path includes a directory named testing. Subdirectories containing a BUILD file are ignored. This should be a very common pattern.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Make the test depend on all txt files in the testdata directory, its subdirectories

java_test(
    name = "mytest",
    srcs = ["mytest.java"],
    data = glob(["testdata/**/*.txt"]),
)

licenses

licenses(license_types)

licenses() specifies the default license type (or types) of the build rules in a BUILD file. The licenses() directive should appear close to the beginning of the BUILD file, before any build rules, as it sets the BUILD-file scope default for build rule license types.

Arguments

The argument, license_types, is a list of license-type strings.

include

include(name)

include() incorporates build language definitions from an external file into the evaluation of the current BUILD file.