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. Examples of such attributes are cc_library.copts and java_library.javacopts. 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 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 genrule.cmd and cc_binary.linkopts. 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.

Attribute Description

List of labels; optional

The list of files needed by this rule at runtime.

Targets named in the data attribute will appear in the *.runfiles area of this rule, if it has one. This may include data files needed by a binary or library, or other programs needed by it. See the data dependencies section for more information about how to depend on and use data files.

Almost all rules permit a data attribute, but where this attribute is not allowed, this fact is documented under the specific rule.


List of labels; optional; default default_visibility from package if specified, or //visibility:private otherwise.

The visibility attribute on a rule controls whether the rule can be used by other packages. Rules are always visible to other rules declared in the same package.

There are five forms (and one temporary form) a visibility label can take:

  • ["//visibility:public"]: Anyone can use this rule.
  • ["//visibility:private"]: Only rules in this package can use this rule. Rules in javatests/foo/bar can always use rules in java/foo/bar.
  • ["//some/package:__pkg__", "//other/package:__pkg__"]: Only rules in some/package and other/package (defined in some/package/BUILD and other/package/BUILD) have access to this rule. Note that sub-packages do not have access to the rule; for example, //some/package/foo:bar or //other/package/testing:bla wouldn't have access. __pkg__ is a special target and must be used verbatim. It represents all of the rules in the package.
  • ["//project:__subpackages__", "//other:__subpackages__"]: Only rules in packages project or other or in one of their sub-packages have access to this rule. For example, //project:rule, //project/library:lib or //other/testing/internal:munge are allowed to depend on this rule (but not //independent:evil)
  • ["//some/package:my_package_group"]: A package group is a named set of package names. Package groups can also grant access rights to entire subtrees, e.g.//myproj/....

The visibility specifications of //visibility:public and //visibility:private can not be combined with any other visibility specifications. A visibility specification may contain a combination of package labels (i.e. //foo:__pkg__) and package_groups.

If a rule does specify the visibility attribute, that specification overrides any default_visibility attribute of the package statement in the BUILD file containing the rule.

Otherwise, if a rule does not specify the visibility attribute, the default_visibility of the package is used (except for exports_files).

Otherwise, if the default_visibility for the package is not specified, //visibility:private is used.


File //frobber/bin/BUILD:

# This rule is visible to everyone
    name = "executable",
    visibility = ["//visibility:public"],
    deps = [":library"],

# This rule is visible only to rules declared in the same package
    name = "library",
    visibility = ["//visibility:private"],

# This rule is visible to rules in package //object and //noun
    name = "subject",
    visibility = [

# See package group "//frobber:friends" (below) for who can
# access this rule.
    name = "thingy",
    visibility = ["//frobber:friends"],

File //frobber/BUILD:

# This is the package group declaration to which rule
# //frobber/bin:thingy refers.
# Our friends are packages //frobber, //fribber and any
# subpackage of //fribber.
    name = "friends",
    packages = [

List of labels; optional

The set of targets whose Make variables the rule is allowed to access. These rules are either rules that provide the TemplateVariableInfo provider or special targets for toolchain types built into Bazel. These include:

  • @bazel_tools//tools/cpp:current_cc_toolchain
  • @bazel_tools//tools/cpp:current_java_runtime

Note that this is distinct from the concept of toolchain resolution that is used by rule implementations for platform-dependenct configuration. You cannot use this attribute to determine which specific cc_toolchain or java_toolchain a target will use.


List of labels; optional

A list of dependencies of this rule.

The precise semantics of what it means for this rule to depend on another using deps are specific to the kind of this rule, and the rule-specific documentation below goes into more detail. At a minimum, though, the targets named via deps will appear in the *.runfiles area of this rule, if it has one.

Most often, a deps dependency is used to allow one module to use symbols defined in another module written in the same programming language and separately compiled. Cross-language dependencies are also permitted in many cases: for example, a java_library rule may depend on C++ code in a cc_library rule, by declaring the latter in the deps attribute. See the definition of dependencies for more information.

Almost all rules permit a deps attribute, but where this attribute is not allowed, this fact is documented under the specific rule.


String; optional

An explanatory warning message associated with this rule. Typically this is used to notify users that a rule has become obsolete, or has become superseded by another rule, is private to a package, or is perhaps considered harmful for some reason. It is a good idea to include some reference (like a webpage, a bug number or example migration CLs) so that one can easily find out what changes are required to avoid the message. If there is a new target that can be used as a drop in replacement, it is a good idea to just migrate all users of the old target.

This attribute has no effect on the way things are built, but it may affect a build tool's diagnostic output. The build tool issues a warning when a rule with a deprecation attribute is depended upon by another rule.

Intra-package dependencies are exempt from this warning, so that, for example, building the tests of a deprecated rule does not encounter a warning.

If a deprecated rule depends on another deprecated rule, no warning message is issued.

Once people have stopped using it, the package can be removed.


List of arbitrary text tags. Tags may be any valid string; default is the empty list.

Tags can be used on any rule. Tags on test and test_suite rules are useful for categorizing the tests. Tags on non-test rules are used to control sandboxed execution of genrules and Starlark actions, and for parsing by humans and/or external tools.

Bazel modifies the behavior of its sandboxing code if it finds the following keywords in the tags attribute of any test rule or genrule, or the keys of execution_requirements for any Starlark action.

  • no-sandbox keyword results in the action or test never being sandboxed; it can still be cached or run remotely - use no-cache or no-remote to prevent either or both of those.
  • no-cache keyword results in the action or test never being cached (remotely or locally)
  • no-remote-cache keyword results in the action or test never being cached remotely (but it may be cached locally; it may also be executed remotely). Note: for the purposes of this tag, the disk-cache is considered a local cache, whereas the http and gRPC caches are considered remote. If a combined cache is specified (i.e. a cache with local and remote components), it's treated as a remote cache and disabled entirely.
  • no-remote-exec keyword results in the action or test never being executed remotely (but it may be cached remotely).
  • no-remote keyword prevents the action or test from being executed remotely or cached remotely. This is equivalent to using both no-remote-cache and no-remote-exec.
  • local keyword precludes the action or test from being remotely cached, remotely executed, or run inside the sandbox. For genrules and tests, marking the rule with the local = True attribute has the same effect.
  • requires-network keyword allows access to the external network from inside the sandbox. This tag only has an effect if sandboxing is enabled.
  • block-network keyword blocks access to the external network from inside the sandbox. In this case, only communication with localhost is allowed. This tag only has an effect if sandboxing is enabled.
  • requires-fakeroot runs the test or action as uid and gid 0 (i.e., the root user). This is only supported on Linux. This tag takes precedence over the --sandbox_fake_username command-line option.

Tags on tests are generally used to annotate a test's role in your debug and release process. Typically, tags are most useful for C++ and Python tests, which lack any runtime annotation ability. The use of tags and size elements gives flexibility in assembling suites of tests based around codebase check-in policy.

Bazel modifies test running behavior if it finds the following keywords in the tags attribute of the test rule:

  • exclusive keyword will force the test to be run in the "exclusive" mode, ensuring that no other tests are running at the same time. Such tests will be executed in serial fashion after all build activity and non-exclusive tests have been completed. They will also always run locally and thus without sandboxing.
  • manual keyword will force the test target to not be included in target pattern wildcards (..., :*, :all, etc); the test target will be neither built nor run. It will also be ignored by the test_suite rules that do not mention this test explicitly. The only way to build or run such a test is to specify it via an explicit target pattern on the command line. Bazel query does not honour the manual tag.
  • external keyword will force test to be unconditionally executed (regardless of --cache_test_results value).
See Tag Conventions in the Test Encyclopedia for more conventions on tags attached to test rules.

Boolean; optional; default False except as noted

If True, only testonly targets (such as tests) can depend on this target.

Equivalently, a rule that is not testonly is not allowed to depend on any rule that is testonly.

Tests (*_test rules) and test suites (test_suite rules) are testonly by default.

This attribute is intended to mean that the target should not be contained in binaries that are released to production.

Because testonly is enforced at build time, not run time, and propagates virally through the dependency tree, it should be applied judiciously. For example, stubs and fakes that are useful for unit tests may also be useful for integration tests involving the same binaries that will be released to production, and therefore should probably not be marked testonly. Conversely, rules that are dangerous to even link in, perhaps because they unconditionally override normal behavior, should definitely be marked testonly.


List of features. Default is the empty list.

Features on a rule modify the features currently enabled on the package level via the features attribute.
For example, if the features ['a', 'b'] are enabled on the package level, and a rule features attribute contains ['-a', 'c'], the features enabled for the rule will be 'b' and 'c'.


List of strings; optional

A list of license-type strings to be used for this particular build rule. This is part of a deprecated licensing API that Bazel no longer uses. Don't use this.


List of labels; optional

The list of environments this rule can be built for, in addition to default-supported environments.

This is part of Bazel's soft-launched constraint system, which lets users declare which rules can and cannot depend on each other. For example, externally deployable binaries shouldn't depend on libraries with company-secret code. See ConstraintSemantics for details.


Dictionary of strings. Default is an empty dictionary.

A dictionary of strings that will be added to the exec_properties of a platform selected for this target. See exec_properties of the platform rule.

If a key is present in both the platform and target-level properties, the value will be taken from the target.


List of strings; optional

A list of distribution-method strings to be used for this particular build rule. This is part of a deprecated licensing API that Bazel no longer uses. Don't use this.


List of labels; optional

A list of constraint_values that must be present in the execution platform for this target. This is in addition to any constraints already set by the rule type. Constraints are used to restrict the list of available execution platforms, see the description of toolchain resolution for details.

This attribute is available only on genrule, shell rules, and all test rules (*_test).


List of labels; optional

The list of environments this rule can be built for, instead of default-supported environments.

This is part of Bazel's soft-launched constraint system. See compatible_with for details.

Attributes common to all test rules (*_test)

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

Attribute Description

List of strings; optional; subject to $(location) and "Make variable" substitution, and Bourne shell tokenization

Add these arguments to the --test_arg when executed by bazel test.

These arguments are passed before the --test_arg values specified on the bazel test command line.


String "enormous", "large" "medium" or "small", default is "medium"; optional

How "heavy" the test is.

A classification of the test's "heaviness": how much time/resources it needs to run.

Unittests are considered "small", integration tests "medium", and end-to-end tests "large" or "enormous". Bazel uses the size to determine a default timeout (which can be overridden using the timeout attribute) and the amount of resources that have to be acquired for the test to run. Test sizes correspond to the following resources and default timeouts:

Size RAM (in MB) CPU (in CPU cores) Default timeout
small 20 1 short (1 minute)
medium 100 1 moderate (5 minutes)
large 300 1 long (15 minutes)
enormous 800 1 eternal (60 minutes)

String "short", "moderate", "long", "eternal" (with the default derived from the test's size attribute)

How long the test is expected to run before returning.

While a test's size attribute controls resource estimation, a test's timeout may be set independently. If not explicitly specified, the timeout is based on the test's size. The test timeout can be overridden with the --test_timeout flag, e.g. for running under certain conditions which are known to be slow. Test timeout values correspond to the following time periods:

Timeout Value Time Period
short 1 minute
moderate 5 minutes
long 15 minutes
eternal 60 minutes

For times other than the above, the test timeout can be overridden with the --test_timeout bazel flag, e.g. for manually running under conditions which are known to be slow. The --test_timeout values are in seconds. For example --test_timeout=120 will set the test timeout to two minutes.


Boolean; optional

Marks test as flaky.

If set, executes the test up to 3 times before being declared as failed. By default this attribute is set to 0 and test is considered to be stable. Note, that use of this attribute is generally discouraged - we do prefer all tests to be stable.


Boolean; optional

Forces the test to be run locally, without sandboxing.

By default this attribute is set to 0 and the default testing strategy is used. This is equivalent to providing "local" as a tag (tags=["local"]).


Non-negative integer less than or equal to 50; optional

Specifies the number of parallel shards to use to run the test.

This value will override any heuristics used to determine the number of parallel shards with which to run the test. Note that for some test rules, this parameter may be required to enable sharding in the first place. Also see --test_sharding_strategy.

Sharding requires the test runner to support the test sharding protocol. If it does not, then it will most likely run every test in every shard, which is not what you want.

Attributes common to all binary rules (*_binary)

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

Attribute Description

List of strings; optional; subject to $(location) and "Make variable" substitution, and Bourne shell tokenization

Command line arguments that bazel will pass to the target when it is executed either by the run command or as a test. These arguments are passed before the ones that are specified on the bazel run or bazel test command line.

NOTE: The arguments are not passed when you run the target outside of bazel (for example, by manually executing the binary in bazel-bin/).

Most binary rules permit an args attribute, but where this attribute is not allowed, this fact is documented under the specific rule.


List of strings; optional

The licenses of the output files that this binary generates. This is part of a deprecated licensing API that Bazel no longer uses. Don't use this.

Configurable attributes

Most attributes are "configurable", meaning that their values may change when the target is built in different ways. Specifically, configurable attributes may vary based on the flags passed to the Bazel command line, or what downstream dependency is requesting the target. This can be used, for instance, to customize the target for multiple platforms or compilation modes.

The following example declares different sources for different target architectures. Running bazel build :multiplatform_lib --cpu x86 will build the target using, while substituting --cpu arm will instead cause it to use

    name = "multiplatform_lib",
    srcs = select({
        ":x86_mode": [""],
        ":arm_mode": [""]
    name = "x86_mode",
    values = { "cpu": "x86" }
    name = "arm_mode",
    values = { "cpu": "arm" }

The select() function chooses among different alternative values for a configurable attribute based on which config_setting criteria is satisfied in the current configuration.

Configurable attributes are evaluated after the processing of macros and before the processing of rules (technically, between the loading and analysis phases. Any processing that Bazel does before the select() is evaluated will not know which branch will be chosen. In particular, macros can't change their behavior based on the chosen branch, and bazel query can only make conservative guesses about the configurable dependencies of a target. Conversely, when authoring a new type of rule, you do not need to worry about the ambiguity of configurable attributes because all select() expressions have already been replaced by their resolved values. See this FAQ for more on using select() with rules and macros.

Attributes marked nonconfigurable in their documentation cannot use this feature. Usually an attribute is nonconfigurable because Bazel internally needs to know its value before it can determine how to choose the select() branch.

See Configurable Build Attributes for more information.

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 global 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.

An important but somewhat subtle distinction between the two namespaces used by the build system: 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.