Project: /_project.yaml
Book: /_book.yaml

# Rules

{% include "_buttons.html" %}

A **rule** defines a series of [**actions**](#actions) that Bazel performs on
inputs to produce a set of outputs, which are referenced in
[**providers**](#providers) returned by the rule's
[**implementation function**](#implementation_function). For example, a C++
binary rule might:

1.  Take a set of `.cpp` source files (inputs).
2.  Run `g++` on the source files (action).
3.  Return the `DefaultInfo` provider with the executable output and other files
    to make available at runtime.
4.  Return the `CcInfo` provider with C++-specific information gathered from the
    target and its dependencies.

From Bazel's perspective, `g++` and the standard C++ libraries are also inputs
to this rule. As a rule writer, you must consider not only the user-provided
inputs to a rule, but also all of the tools and libraries required to execute
the actions.

Before creating or modifying any rule, ensure you are familiar with Bazel's
[build phases](/extending/concepts). It is important to understand the three
phases of a build (loading, analysis, and execution). It is also useful to
learn about [macros](/extending/macros) to understand the difference between rules and
macros. To get started, first review the [Rules Tutorial](/rules/rules-tutorial).
Then, use this page as a reference.

A few rules are built into Bazel itself. These *native rules*, such as
`genrule` and `filegroup`, provide some core support.
By defining your own rules, you can add support for languages and tools
that Bazel doesn't support natively.

Bazel provides an extensibility model for writing rules using the
[Starlark](/rules/language) language. These rules are written in `.bzl` files, which
can be loaded directly from `BUILD` files.

When defining your own rule, you get to decide what attributes it supports and
how it generates its outputs.

The rule's `implementation` function defines its exact behavior during the
[analysis phase](/extending/concepts#evaluation-model). This function doesn't run any
external commands. Rather, it registers [actions](#actions) that will be used
later during the execution phase to build the rule's outputs, if they are
needed.

## Rule creation

In a `.bzl` file, use the [rule](/rules/lib/globals/bzl#rule) function to define a new
rule, and store the result in a global variable. The call to `rule` specifies
[attributes](#attributes) and an
[implementation function](#implementation_function):

```python
example_library = rule(
    implementation = _example_library_impl,
    attrs = {
        "deps": attr.label_list(),
        ...
    },
)
```

This defines a [rule kind](/query/language#kind) named `example_library`.

The call to `rule` also must specify if the rule creates an
[executable](#executable-rules) output (with `executable = True`), or specifically
a test executable (with `test = True`). If the latter, the rule is a *test rule*,
and the name of the rule must end in `_test`.

## Target instantiation

Rules can be [loaded](/concepts/build-files#load) and called in `BUILD` files:

```python
load('//some/pkg:rules.bzl', 'example_library')

example_library(
    name = "example_target",
    deps = [":another_target"],
    ...
)
```

Each call to a build rule returns no value, but has the side effect of defining
a target. This is called *instantiating* the rule. This specifies a name for the
new target and values for the target's [attributes](#attributes).

Rules can also be called from Starlark functions and loaded in `.bzl` files.
Starlark functions that call rules are called [Starlark macros](/extending/macros).
Starlark macros must ultimately be called from `BUILD` files, and can only be
called during the [loading phase](/extending/concepts#evaluation-model), when `BUILD`
files are evaluated to instantiate targets.

## Attributes

An *attribute* is a rule argument. Attributes can provide specific values to a
target's [implementation](#implementation_function), or they can refer to other
targets, creating a graph of dependencies.

Rule-specific attributes, such as `srcs` or `deps`, are defined by passing a map
from attribute names to schemas (created using the [`attr`](/rules/lib/toplevel/attr)
module) to the `attrs` parameter of `rule`.
[Common attributes](/reference/be/common-definitions#common-attributes), such as
`name` and `visibility`, are implicitly added to all rules. Additional
attributes are implicitly added to
[executable and test rules](#executable-rules) specifically. Attributes which
are implicitly added to a rule can't be included in the dictionary passed to
`attrs`.

### Dependency attributes

Rules that process source code usually define the following attributes to handle
various [types of dependencies](/concepts/dependencies#types_of_dependencies):

*   `srcs` specifies source files processed by a target's actions. Often, the
    attribute schema specifies which file extensions are expected for the sort
    of source file the rule processes. Rules for languages with header files
    generally specify a separate `hdrs` attribute for headers processed by a
    target and its consumers.
*   `deps` specifies code dependencies for a target. The attribute schema should
    specify which [providers](#providers) those dependencies must provide. (For
    example, `cc_library` provides `CcInfo`.)
*   `data` specifies files to be made available at runtime to any executable
    which depends on a target. That should allow arbitrary files to be
    specified.

```python
example_library = rule(
    implementation = _example_library_impl,
    attrs = {
        "srcs": attr.label_list(allow_files = [".example"]),
        "hdrs": attr.label_list(allow_files = [".header"]),
        "deps": attr.label_list(providers = [ExampleInfo]),
        "data": attr.label_list(allow_files = True),
        ...
    },
)
```

These are examples of *dependency attributes*. Any attribute that specifies
an input label (those defined with
[`attr.label_list`](/rules/lib/toplevel/attr#label_list),
[`attr.label`](/rules/lib/toplevel/attr#label), or
[`attr.label_keyed_string_dict`](/rules/lib/toplevel/attr#label_keyed_string_dict))
specifies dependencies of a certain type
between a target and the targets whose labels (or the corresponding
[`Label`](/rules/lib/builtins/Label) objects) are listed in that attribute when the target
is defined. The repository, and possibly the path, for these labels is resolved
relative to the defined target.

```python
example_library(
    name = "my_target",
    deps = [":other_target"],
)

example_library(
    name = "other_target",
    ...
)
```

In this example, `other_target` is a dependency of `my_target`, and therefore
`other_target` is analyzed first. It is an error if there is a cycle in the
dependency graph of targets.

<a name="private-attributes"></a>

### Private attributes and implicit dependencies {:#private_attributes_and_implicit_dependencies}

A dependency attribute with a default value creates an *implicit dependency*. It
is implicit because it's a part of the target graph that the user doesn't
specify it in a `BUILD` file. Implicit dependencies are useful for hard-coding a
relationship between a rule and a *tool* (a build-time dependency, such as a
compiler), since most of the time a user is not interested in specifying what
tool the rule uses. Inside the rule's implementation function, this is treated
the same as other dependencies.

If you want to provide an implicit dependency without allowing the user to
override that value, you can make the attribute *private* by giving it a name
that begins with an underscore (`_`). Private attributes must have default
values. It generally only makes sense to use private attributes for implicit
dependencies.

```python
example_library = rule(
    implementation = _example_library_impl,
    attrs = {
        ...
        "_compiler": attr.label(
            default = Label("//tools:example_compiler"),
            allow_single_file = True,
            executable = True,
            cfg = "exec",
        ),
    },
)
```

In this example, every target of type `example_library` has an implicit
dependency on the compiler `//tools:example_compiler`. This allows
`example_library`'s implementation function to generate actions that invoke the
compiler, even though the user did not pass its label as an input. Since
`_compiler` is a private attribute, it follows that `ctx.attr._compiler`
will always point to `//tools:example_compiler` in all targets of this rule
type. Alternatively, you can name the attribute `compiler` without the
underscore and keep the default value. This allows users to substitute a
different compiler if necessary, but it requires no awareness of the compiler's
label.

Implicit dependencies are generally used for tools that reside in the same
repository as the rule implementation. If the tool comes from the
[execution platform](/extending/platforms) or a different repository instead, the
rule should obtain that tool from a [toolchain](/extending/toolchains).

### Output attributes

*Output attributes*, such as [`attr.output`](/rules/lib/toplevel/attr#output) and
[`attr.output_list`](/rules/lib/toplevel/attr#output_list), declare an output file that the
target generates. These differ from dependency attributes in two ways:

*   They define output file targets instead of referring to targets defined
    elsewhere.
*   The output file targets depend on the instantiated rule target, instead of
    the other way around.

Typically, output attributes are only used when a rule needs to create outputs
with user-defined names which can't be based on the target name. If a rule has
one output attribute, it is typically named `out` or `outs`.

Output attributes are the preferred way of creating *predeclared outputs*, which
can be specifically depended upon or
[requested at the command line](#requesting_output_files).

## Implementation function

Every rule requires an `implementation` function. These functions are executed
strictly in the [analysis phase](/extending/concepts#evaluation-model) and transform the
graph of targets generated in the loading phase into a graph of
[actions](#actions) to be performed during the execution phase. As such,
implementation functions can't actually read or write files.

Rule implementation functions are usually private (named with a leading
underscore). Conventionally, they are named the same as their rule, but suffixed
with `_impl`.

Implementation functions take exactly one parameter: a
[rule context](/rules/lib/builtins/ctx), conventionally named `ctx`. They return a list of
[providers](#providers).

### Targets

Dependencies are represented at analysis time as [`Target`](/rules/lib/builtins/Target)
objects. These objects contain the [providers](#providers) generated when the
target's implementation function was executed.

[`ctx.attr`](/rules/lib/builtins/ctx#attr) has fields corresponding to the names of each
dependency attribute, containing `Target` objects representing each direct
dependency using that attribute. For `label_list` attributes, this is a list of
`Targets`. For `label` attributes, this is a single `Target` or `None`.

A list of provider objects are returned by a target's implementation function:

```python
return [ExampleInfo(headers = depset(...))]
```

Those can be accessed using index notation (`[]`), with the type of provider as
a key. These can be [custom providers](#custom_providers) defined in Starlark or
[providers for native rules](/rules/lib/providers) available as Starlark
global variables.

For example, if a rule takes header files using a `hdrs` attribute and provides
them to the compilation actions of the target and its consumers, it could
collect them like so:

```python
def _example_library_impl(ctx):
    ...
    transitive_headers = [hdr[ExampleInfo].headers for hdr in ctx.attr.hdrs]
```

There's a legacy struct style, which is strongly discouraged and rules should be
[migrated away from it](#migrating_from_legacy_providers).

### Files

Files are represented by [`File`](/rules/lib/builtins/File) objects. Since Bazel doesn't
perform file I/O during the analysis phase, these objects can't be used to
directly read or write file content. Rather, they are passed to action-emitting
functions (see [`ctx.actions`](/rules/lib/builtins/actions)) to construct pieces of the
action graph.

A `File` can either be a source file or a generated file. Each generated file
must be an output of exactly one action. Source files can't be the output of
any action.

For each dependency attribute, the corresponding field of
[`ctx.files`](/rules/lib/builtins/ctx#files) contains a list of the default outputs of all
dependencies using that attribute:

```python
def _example_library_impl(ctx):
    ...
    headers = depset(ctx.files.hdrs, transitive = transitive_headers)
    srcs = ctx.files.srcs
    ...
```

[`ctx.file`](/rules/lib/builtins/ctx#file) contains a single `File` or `None` for
dependency attributes whose specs set `allow_single_file = True`.
[`ctx.executable`](/rules/lib/builtins/ctx#executable) behaves the same as `ctx.file`, but only
contains fields for dependency attributes whose specs set `executable = True`.

### Declaring outputs

During the analysis phase, a rule's implementation function can create outputs.
Since all labels have to be known during the loading phase, these additional
outputs have no labels. `File` objects for outputs can be created using
[`ctx.actions.declare_file`](/rules/lib/builtins/actions#declare_file) and
[`ctx.actions.declare_directory`](/rules/lib/builtins/actions#declare_directory).
Often, the names of outputs are based on the target's name,
[`ctx.label.name`](/rules/lib/builtins/ctx#label):

```python
def _example_library_impl(ctx):
  ...
  output_file = ctx.actions.declare_file(ctx.label.name + ".output")
  ...
```

For *predeclared outputs*, like those created for
[output attributes](#output_attributes), `File` objects instead can be retrieved
from the corresponding fields of [`ctx.outputs`](/rules/lib/builtins/ctx#outputs).

### Actions

An action describes how to generate a set of outputs from a set of inputs, for
example "run gcc on hello.c and get hello.o". When an action is created, Bazel
doesn't run the command immediately. It registers it in a graph of dependencies,
because an action can depend on the output of another action. For example, in C,
the linker must be called after the compiler.

General-purpose functions that create actions are defined in
[`ctx.actions`](/rules/lib/builtins/actions):

*   [`ctx.actions.run`](/rules/lib/builtins/actions#run), to run an executable.
*   [`ctx.actions.run_shell`](/rules/lib/builtins/actions#run_shell), to run a shell
    command.
*   [`ctx.actions.write`](/rules/lib/builtins/actions#write), to write a string to a file.
*   [`ctx.actions.expand_template`](/rules/lib/builtins/actions#expand_template), to
    generate a file from a template.

[`ctx.actions.args`](/rules/lib/builtins/actions#args) can be used to efficiently
accumulate the arguments for actions. It avoids flattening depsets until
execution time:

```python
def _example_library_impl(ctx):
    ...

    transitive_headers = [dep[ExampleInfo].headers for dep in ctx.attr.deps]
    headers = depset(ctx.files.hdrs, transitive = transitive_headers)
    srcs = ctx.files.srcs
    inputs = depset(srcs, transitive = [headers])
    output_file = ctx.actions.declare_file(ctx.label.name + ".output")

    args = ctx.actions.args()
    args.add_joined("-h", headers, join_with = ",")
    args.add_joined("-s", srcs, join_with = ",")
    args.add("-o", output_file)

    ctx.actions.run(
        mnemonic = "ExampleCompile",
        executable = ctx.executable._compiler,
        arguments = [args],
        inputs = inputs,
        outputs = [output_file],
    )
    ...
```

Actions take a list or depset of input files and generate a (non-empty) list of
output files. The set of input and output files must be known during the
[analysis phase](/extending/concepts#evaluation-model). It might depend on the value of
attributes, including providers from dependencies, but it can't depend on the
result of the execution. For example, if your action runs the unzip command, you
must specify which files you expect to be inflated (before running unzip).
Actions which create a variable number of files internally can wrap those in a
single file (such as a zip, tar, or other archive format).

Actions must list all of their inputs. Listing inputs that are not used is
permitted, but inefficient.

Actions must create all of their outputs. They may write other files, but
anything not in outputs won't be available to consumers. All declared outputs
must be written by some action.

Actions are comparable to pure functions: They should depend only on the
provided inputs, and avoid accessing computer information, username, clock,
network, or I/O devices (except for reading inputs and writing outputs). This is
important because the output will be cached and reused.

Dependencies are resolved by Bazel, which decides which actions to
execute. It is an error if there is a cycle in the dependency graph. Creating
an action doesn't guarantee that it will be executed, that depends on whether
its outputs are needed for the build.

### Providers

Providers are pieces of information that a rule exposes to other rules that
depend on it. This data can include output files, libraries, parameters to pass
on a tool's command line, or anything else a target's consumers should know
about.

Since a rule's implementation function can only read providers from the
instantiated target's immediate dependencies, rules need to forward any
information from a target's dependencies that needs to be known by a target's
consumers, generally by accumulating that into a [`depset`](/rules/lib/builtins/depset).

A target's providers are specified by a list of provider objects returned by
the implementation function.

Old implementation functions can also be written in a legacy style where the
implementation function returns a [`struct`](/rules/lib/builtins/struct) instead of list of
provider objects. This style is strongly discouraged and rules should be
[migrated away from it](#migrating_from_legacy_providers).

#### Default outputs

A target's *default outputs* are the outputs that are requested by default when
the target is requested for build at the command line. For example, a
`java_library` target `//pkg:foo` has `foo.jar` as a default output, so that
will be built by the command `bazel build //pkg:foo`.

Default outputs are specified by the `files` parameter of
[`DefaultInfo`](/rules/lib/providers/DefaultInfo):

```python
def _example_library_impl(ctx):
    ...
    return [
        DefaultInfo(files = depset([output_file]), ...),
        ...
    ]
```

If `DefaultInfo` is not returned by a rule implementation or the `files`
parameter is not specified, `DefaultInfo.files` defaults to all
*predeclared outputs* (generally, those created by [output
attributes](#output_attributes)).

Rules that perform actions should provide default outputs, even if those outputs
are not expected to be directly used. Actions that are not in the graph of the
requested outputs are pruned. If an output is only used by a target's consumers,
those actions won't be performed when the target is built in isolation. This
makes debugging more difficult because rebuilding just the failing target won't
reproduce the failure.

#### Runfiles

Runfiles are a set of files used by a target at runtime (as opposed to build
time). During the [execution phase](/extending/concepts#evaluation-model), Bazel creates
a directory tree containing symlinks pointing to the runfiles. This stages the
environment for the binary so it can access the runfiles during runtime.

Runfiles can be added manually during rule creation.
[`runfiles`](/rules/lib/builtins/runfiles) objects can be created by the `runfiles` method
on the rule context, [`ctx.runfiles`](/rules/lib/builtins/ctx#runfiles) and passed to the
`runfiles` parameter on `DefaultInfo`. The executable output of
[executable rules](#executable-rules) is implicitly added to the runfiles.

Some rules specify attributes, generally named
[`data`](/reference/be/common-definitions#common.data), whose outputs are added to
a targets' runfiles. Runfiles should also be merged in from `data`, as well as
from any attributes which might provide code for eventual execution, generally
`srcs` (which might contain `filegroup` targets with associated `data`) and
`deps`.

```python
def _example_library_impl(ctx):
    ...
    runfiles = ctx.runfiles(files = ctx.files.data)
    transitive_runfiles = []
    for runfiles_attr in (
        ctx.attr.srcs,
        ctx.attr.hdrs,
        ctx.attr.deps,
        ctx.attr.data,
    ):
        for target in runfiles_attr:
            transitive_runfiles.append(target[DefaultInfo].default_runfiles)
    runfiles = runfiles.merge_all(transitive_runfiles)
    return [
        DefaultInfo(..., runfiles = runfiles),
        ...
    ]
```

#### Custom providers

Providers can be defined using the [`provider`](/rules/lib/globals/bzl#provider)
function to convey rule-specific information:

```python
ExampleInfo = provider(
    "Info needed to compile/link Example code.",
    fields = {
        "headers": "depset of header Files from transitive dependencies.",
        "files_to_link": "depset of Files from compilation.",
    },
)
```

Rule implementation functions can then construct and return provider instances:

```python
def _example_library_impl(ctx):
  ...
  return [
      ...
      ExampleInfo(
          headers = headers,
          files_to_link = depset(
              [output_file],
              transitive = [
                  dep[ExampleInfo].files_to_link for dep in ctx.attr.deps
              ],
          ),
      )
  ]
```

##### Custom initialization of providers

It's possible to guard the instantiation of a provider with custom
preprocessing and validation logic. This can be used to ensure that all
provider instances satisfy certain invariants, or to give users a cleaner API for
obtaining an instance.

This is done by passing an `init` callback to the
[`provider`](/rules/lib/globals/bzl.html#provider) function. If this callback is given, the
return type of `provider()` changes to be a tuple of two values: the provider
symbol that is the ordinary return value when `init` is not used, and a "raw
constructor".

In this case, when the provider symbol is called, instead of directly returning
a new instance, it will forward the arguments along to the `init` callback. The
callback's return value must be a dict mapping field names (strings) to values;
this is used to initialize the fields of the new instance. Note that the
callback may have any signature, and if the arguments don't match the signature
an error is reported as if the callback were invoked directly.

The raw constructor, by contrast, will bypass the `init` callback.

The following example uses `init` to preprocess and validate its arguments:

```python
# //pkg:exampleinfo.bzl

_core_headers = [...]  # private constant representing standard library files

# Keyword-only arguments are preferred.
def _exampleinfo_init(*, files_to_link, headers = None, allow_empty_files_to_link = False):
    if not files_to_link and not allow_empty_files_to_link:
        fail("files_to_link may not be empty")
    all_headers = depset(_core_headers, transitive = headers)
    return {"files_to_link": files_to_link, "headers": all_headers}

ExampleInfo, _new_exampleinfo = provider(
    fields = ["files_to_link", "headers"],
    init = _exampleinfo_init,
)
```

A rule implementation may then instantiate the provider as follows:

```python
ExampleInfo(
    files_to_link = my_files_to_link,  # may not be empty
    headers = my_headers,  # will automatically include the core headers
)
```

The raw constructor can be used to define alternative public factory functions
that don't go through the `init` logic. For example, exampleinfo.bzl
could define:

```python
def make_barebones_exampleinfo(headers):
    """Returns an ExampleInfo with no files_to_link and only the specified headers."""
    return _new_exampleinfo(files_to_link = depset(), headers = all_headers)
```

Typically, the raw constructor is bound to a variable whose name begins with an
underscore (`_new_exampleinfo` above), so that user code can't load it and
generate arbitrary provider instances.

Another use for `init` is to prevent the user from calling the provider
symbol altogether, and force them to use a factory function instead:

```python
def _exampleinfo_init_banned(*args, **kwargs):
    fail("Do not call ExampleInfo(). Use make_exampleinfo() instead.")

ExampleInfo, _new_exampleinfo = provider(
    ...
    init = _exampleinfo_init_banned)

def make_exampleinfo(...):
    ...
    return _new_exampleinfo(...)
```

<a name="executable-rules"></a>

## Executable rules and test rules

Executable rules define targets that can be invoked by a `bazel run` command.
Test rules are a special kind of executable rule whose targets can also be
invoked by a `bazel test` command. Executable and test rules are created by
setting the respective [`executable`](/rules/lib/globals/bzl#rule.executable) or
[`test`](/rules/lib/globals/bzl#rule.test) argument to `True` in the call to `rule`:

```python
example_binary = rule(
   implementation = _example_binary_impl,
   executable = True,
   ...
)

example_test = rule(
   implementation = _example_binary_impl,
   test = True,
   ...
)
```

Test rules must have names that end in `_test`. (Test *target* names also often
end in `_test` by convention, but this is not required.) Non-test rules must not
have this suffix.

Both kinds of rules must produce an executable output file (which may or may not
be predeclared) that will be invoked by the `run` or `test` commands. To tell
Bazel which of a rule's outputs to use as this executable, pass it as the
`executable` argument of a returned [`DefaultInfo`](/rules/lib/providers/DefaultInfo)
provider. That `executable` is added to the default outputs of the rule (so you
don't need to pass that to both `executable` and `files`). It's also implicitly
added to the [runfiles](#runfiles):

```python
def _example_binary_impl(ctx):
    executable = ctx.actions.declare_file(ctx.label.name)
    ...
    return [
        DefaultInfo(executable = executable, ...),
        ...
    ]
```

The action that generates this file must set the executable bit on the file. For
a [`ctx.actions.run`](/rules/lib/builtins/actions#run) or
[`ctx.actions.run_shell`](/rules/lib/builtins/actions#run_shell) action this should be done
by the underlying tool that is invoked by the action. For a
[`ctx.actions.write`](/rules/lib/builtins/actions#write) action, pass `is_executable = True`.

As [legacy behavior](#deprecated_predeclared_outputs), executable rules have a
special `ctx.outputs.executable` predeclared output. This file serves as the
default executable if you don't specify one using `DefaultInfo`; it must not be
used otherwise. This output mechanism is deprecated because it doesn't support
customizing the executable file's name at analysis time.

See examples of an
[executable rule](https://github.com/bazelbuild/examples/blob/main/rules/executable/fortune.bzl){: .external}
and a
[test rule](https://github.com/bazelbuild/examples/blob/main/rules/test_rule/line_length.bzl){: .external}.

[Executable rules](/reference/be/common-definitions#common-attributes-binaries) and
[test rules](/reference/be/common-definitions#common-attributes-tests) have additional
attributes implicitly defined, in addition to those added for
[all rules](/reference/be/common-definitions#common-attributes). The defaults of
implicitly-added attributes can't be changed, though this can be worked around
by wrapping a private rule in a [Starlark macro](/extending/macros) which alters the
default:

```python
def example_test(size = "small", **kwargs):
  _example_test(size = size, **kwargs)

_example_test = rule(
 ...
)
```

### Runfiles location

When an executable target is run with `bazel run` (or `test`), the root of the
runfiles directory is adjacent to the executable. The paths relate as follows:

```python
# Given launcher_path and runfile_file:
runfiles_root = launcher_path.path + ".runfiles"
workspace_name = ctx.workspace_name
runfile_path = runfile_file.short_path
execution_root_relative_path = "%s/%s/%s" % (
    runfiles_root, workspace_name, runfile_path)
```

The path to a `File` under the runfiles directory corresponds to
[`File.short_path`](/rules/lib/builtins/File#short_path).

The binary executed directly by `bazel` is adjacent to the root of the
`runfiles` directory. However, binaries called *from* the runfiles can't make
the same assumption. To mitigate this, each binary should provide a way to
accept its runfiles root as a parameter using an environment, or command line
argument or flag. This allows binaries to pass the correct canonical runfiles root
to the binaries it calls. If that's not set, a binary can guess that it was the
first binary called and look for an adjacent runfiles directory.

## Advanced topics

### Requesting output files

A single target can have several output files. When a `bazel build` command is
run, some of the outputs of the targets given to the command are considered to
be *requested*. Bazel only builds these requested files and the files that they
directly or indirectly depend on. (In terms of the action graph, Bazel only
executes the actions that are reachable as transitive dependencies of the
requested files.)

In addition to [default outputs](#default_outputs), any *predeclared output* can
be explicitly requested on the command line. Rules can specify predeclared
outputs using [output attributes](#output_attributes). In that case, the user
explicitly chooses labels for outputs when they instantiate the rule. To obtain
[`File`](/rules/lib/builtins/File) objects for output attributes, use the corresponding
attribute of [`ctx.outputs`](/rules/lib/builtins/ctx#outputs). Rules can
[implicitly define predeclared outputs](#deprecated_predeclared_outputs) based
on the target name as well, but this feature is deprecated.

In addition to default outputs, there are *output groups*, which are collections
of output files that may be requested together. These can be requested with
[`--output_groups`](/reference/command-line-reference#flag--output_groups). For
example, if a target `//pkg:mytarget` is of a rule type that has a `debug_files`
output group, these files can be built by running `bazel build //pkg:mytarget
--output_groups=debug_files`. Since non-predeclared outputs don't have labels,
they can only be requested by appearing in the default outputs or an output
group.

Output groups can be specified with the
[`OutputGroupInfo`](/rules/lib/providers/OutputGroupInfo) provider. Note that unlike many
built-in providers, `OutputGroupInfo` can take parameters with arbitrary names
to define output groups with that name:

```python
def _example_library_impl(ctx):
    ...
    debug_file = ctx.actions.declare_file(name + ".pdb")
    ...
    return [
        DefaultInfo(files = depset([output_file]), ...),
        OutputGroupInfo(
            debug_files = depset([debug_file]),
            all_files = depset([output_file, debug_file]),
        ),
        ...
    ]
```

Also unlike most providers, `OutputGroupInfo` can be returned by both an
[aspect](/extending/aspects) and the rule target to which that aspect is applied, as
long as they don't define the same output groups. In that case, the resulting
providers are merged.

Note that `OutputGroupInfo` generally shouldn't be used to convey specific sorts
of files from a target to the actions of its consumers. Define
[rule-specific providers](#custom_providers) for that instead.

### Configurations

Imagine that you want to build a C++ binary for a different architecture. The
build can be complex and involve multiple steps. Some of the intermediate
binaries, like compilers and code generators, have to run on
[the execution platform](/extending/platforms#overview) (which could be your host,
or a remote executor). Some binaries like the final output must be built for the
target architecture.

For this reason, Bazel has a concept of "configurations" and transitions. The
topmost targets (the ones requested on the command line) are built-in the
"target" configuration, while tools that should run on the execution platform
are built-in an "exec" configuration. Rules may generate different actions based
on the configuration, for instance to change the cpu architecture that is passed
to the compiler. In some cases, the same library may be needed for different
configurations. If this happens, it will be analyzed and potentially built
multiple times.

By default, Bazel builds a target's dependencies in the same configuration as
the target itself, in other words without transitions. When a dependency is a
tool that's needed to help build the target, the corresponding attribute should
specify a transition to an exec configuration. This causes the tool and all its
dependencies to build for the execution platform.

For each dependency attribute, you can use `cfg` to decide if dependencies
should build in the same configuration or transition to an exec configuration.
If a dependency attribute has the flag `executable = True`, `cfg` must be set
explicitly. This is to guard against accidentally building a tool for the wrong
configuration.
[See example](https://github.com/bazelbuild/examples/blob/main/rules/actions_run/execute.bzl){: .external}

In general, sources, dependent libraries, and executables that will be needed at
runtime can use the same configuration.

Tools that are executed as part of the build (such as compilers or code generators)
should be built for an exec configuration. In this case, specify `cfg = "exec"` in
the attribute.

Otherwise, executables that are used at runtime (such as as part of a test) should
be built for the target configuration. In this case, specify `cfg = "target"` in
the attribute.

`cfg = "target"` doesn't actually do anything: it's purely a convenience value to
help rule designers be explicit about their intentions. When `executable = False`,
which means `cfg` is optional, only set this when it truly helps readability.

You can also use `cfg = my_transition` to use
[user-defined transitions](/extending/config#user-defined-transitions), which allow
rule authors a great deal of flexibility in changing configurations, with the
drawback of
[making the build graph larger and less comprehensible](/extending/config#memory-and-performance-considerations).

**Note**: Historically, Bazel didn't have the concept of execution platforms,
and instead all build actions were considered to run on the host machine. Bazel
versions before 6.0 created a distinct "host" configuration to represent this.
If you see references to "host" in code or old documentation, that's what this
refers to. We recommend using Bazel 6.0 or newer to avoid this extra conceptual
overhead.

<a name="fragments"></a>

### Configuration fragments

Rules may access
[configuration fragments](/rules/lib/fragments) such as
`cpp` and `java`. However, all required fragments must be declared in
order to avoid access errors:

```python
def _impl(ctx):
    # Using ctx.fragments.cpp leads to an error since it was not declared.
    x = ctx.fragments.java
    ...

my_rule = rule(
    implementation = _impl,
    fragments = ["java"],      # Required fragments of the target configuration
    ...
)
```

### Runfiles symlinks

Normally, the relative path of a file in the runfiles tree is the same as the
relative path of that file in the source tree or generated output tree. If these
need to be different for some reason, you can specify the `root_symlinks` or
`symlinks` arguments. The `root_symlinks` is a dictionary mapping paths to
files, where the paths are relative to the root of the runfiles directory. The
`symlinks` dictionary is the same, but paths are implicitly prefixed with the
name of the main workspace (*not* the name of the repository containing the
current target).

```python
    ...
    runfiles = ctx.runfiles(
        root_symlinks = {"some/path/here.foo": ctx.file.some_data_file2}
        symlinks = {"some/path/here.bar": ctx.file.some_data_file3}
    )
    # Creates something like:
    # sometarget.runfiles/
    #     some/
    #         path/
    #             here.foo -> some_data_file2
    #     <workspace_name>/
    #         some/
    #             path/
    #                 here.bar -> some_data_file3
```

If `symlinks` or `root_symlinks` is used, be careful not to map two different
files to the same path in the runfiles tree. This will cause the build to fail
with an error describing the conflict. To fix, you will need to modify your
`ctx.runfiles` arguments to remove the collision. This checking will be done for
any targets using your rule, as well as targets of any kind that depend on those
targets. This is especially risky if your tool is likely to be used transitively
by another tool; symlink names must be unique across the runfiles of a tool and
all of its dependencies.

### Code coverage

When the [`coverage`](/reference/command-line-reference#coverage) command is run,
the build may need to add coverage instrumentation for certain targets. The
build also gathers the list of source files that are instrumented. The subset of
targets that are considered is controlled by the flag
[`--instrumentation_filter`](/reference/command-line-reference#flag--instrumentation_filter).
Test targets are excluded, unless
[`--instrument_test_targets`](/reference/command-line-reference#flag--instrument_test_targets)
is specified.

If a rule implementation adds coverage instrumentation at build time, it needs
to account for that in its implementation function.
[ctx.coverage_instrumented](/rules/lib/builtins/ctx#coverage_instrumented) returns
`True` in coverage mode if a target's sources should be instrumented:

```python
# Are this rule's sources instrumented?
if ctx.coverage_instrumented():
  # Do something to turn on coverage for this compile action
```

Logic that always needs to be on in coverage mode (whether a target's sources
specifically are instrumented or not) can be conditioned on
[ctx.configuration.coverage_enabled](/rules/lib/builtins/configuration#coverage_enabled).

If the rule directly includes sources from its dependencies before compilation
(such as header files), it may also need to turn on compile-time instrumentation if
the dependencies' sources should be instrumented:

```python
# Are this rule's sources or any of the sources for its direct dependencies
# in deps instrumented?
if (ctx.configuration.coverage_enabled and
    (ctx.coverage_instrumented() or
     any([ctx.coverage_instrumented(dep) for dep in ctx.attr.deps]))):
    # Do something to turn on coverage for this compile action
```

Rules also should provide information about which attributes are relevant for
coverage with the `InstrumentedFilesInfo` provider, constructed using
[`coverage_common.instrumented_files_info`](/rules/lib/toplevel/coverage_common#instrumented_files_info).
The `dependency_attributes` parameter of `instrumented_files_info` should list
all runtime dependency attributes, including code dependencies like `deps` and
data dependencies like `data`. The `source_attributes` parameter should list the
rule's source files attributes if coverage instrumentation might be added:

```python
def _example_library_impl(ctx):
    ...
    return [
        ...
        coverage_common.instrumented_files_info(
            ctx,
            dependency_attributes = ["deps", "data"],
            # Omitted if coverage is not supported for this rule:
            source_attributes = ["srcs", "hdrs"],
        )
        ...
    ]
```

If `InstrumentedFilesInfo` is not returned, a default one is created with each
non-tool [dependency attribute](#dependency_attributes) that doesn't set
[`cfg`](#configuration) to `"exec"` in the attribute schema. in
`dependency_attributes`. (This isn't ideal behavior, since it puts attributes
like `srcs` in `dependency_attributes` instead of `source_attributes`, but it
avoids the need for explicit coverage configuration for all rules in the
dependency chain.)

### Validation Actions

Sometimes you need to validate something about the build, and the
information required to do that validation is available only in artifacts
(source files or generated files). Because this information is in artifacts,
rules can't do this validation at analysis time because rules can't read
files. Instead, actions must do this validation at execution time. When
validation fails, the action will fail, and hence so will the build.

Examples of validations that might be run are static analysis, linting,
dependency and consistency checks, and style checks.

Validation actions can also help to improve build performance by moving parts
of actions that are not required for building artifacts into separate actions.
For example, if a single action that does compilation and linting can be
separated into a compilation action and a linting action, then the linting
action can be run as a validation action and run in parallel with other actions.

These "validation actions" often don't produce anything that is used elsewhere
in the build, since they only need to assert things about their inputs. This
presents a problem though: If a validation action doesn't produce anything that
is used elsewhere in the build, how does a rule get the action to run?
Historically, the approach was to have the validation action output an empty
file, and artificially add that output to the inputs of some other important
action in the build:

<img src="/rules/validation_action_historical.svg" width="35%" />

This works, because Bazel will always run the validation action when the compile
action is run, but this has significant drawbacks:

1. The validation action is in the critical path of the build. Because Bazel
thinks the empty output is required to run the compile action, it will run the
validation action first, even though the compile action will ignore the input.
This reduces parallelism and slows down builds.

2. If other actions in the build might run instead of the
compile action, then the empty outputs of validation actions need to be added to
those actions as well (`java_library`'s source jar output, for example). This is
also a problem if new actions that might run instead of the compile action are
added later, and the empty validation output is accidentally left off.

The solution to these problems is to use the Validations Output Group.

#### Validations Output Group

The Validations Output Group is an output group designed to hold the otherwise
unused outputs of validation actions, so that they don't need to be artificially
added to the inputs of other actions.

This group is special in that its outputs are always requested, regardless of
the value of the `--output_groups` flag, and regardless of how the target is
depended upon (for example, on the command line, as a dependency, or through
implicit outputs of the target). Note that normal caching and incrementality
still apply: if the inputs to the validation action have not changed and the
validation action previously succeeded, then the validation action won't be
run.

<img src="/rules/validation_action.svg" width="35%" />

Using this output group still requires that validation actions output some file,
even an empty one. This might require wrapping some tools that normally don't
create outputs so that a file is created.

A target's validation actions are not run in three cases:

*    When the target is depended upon as a tool
*    When the target is depended upon as an implicit dependency (for example, an
     attribute that starts with "_")
*    When the target is built in the exec configuration.

It is assumed that these targets have their own
separate builds and tests that would uncover any validation failures.

#### Using the Validations Output Group

The Validations Output Group is named `_validation` and is used like any other
output group:

```python
def _rule_with_validation_impl(ctx):

  ctx.actions.write(ctx.outputs.main, "main output\n")
  ctx.actions.write(ctx.outputs.implicit, "implicit output\n")

  validation_output = ctx.actions.declare_file(ctx.attr.name + ".validation")
  ctx.actions.run(
    outputs = [validation_output],
    executable = ctx.executable._validation_tool,
    arguments = [validation_output.path],
  )

  return [
    DefaultInfo(files = depset([ctx.outputs.main])),
    OutputGroupInfo(_validation = depset([validation_output])),
  ]


rule_with_validation = rule(
  implementation = _rule_with_validation_impl,
  outputs = {
    "main": "%{name}.main",
    "implicit": "%{name}.implicit",
  },
  attrs = {
    "_validation_tool": attr.label(
        default = Label("//validation_actions:validation_tool"),
        executable = True,
        cfg = "exec"
    ),
  }
)
```

Notice that the validation output file is not added to the `DefaultInfo` or the
inputs to any other action. The validation action for a target of this rule kind
will still run if the target is depended upon by label, or any of the target's
implicit outputs are directly or indirectly depended upon.

It is usually important that the outputs of validation actions only go into the
validation output group, and are not added to the inputs of other actions, as
this could defeat parallelism gains. Note however that Bazel doesn't
have any special checking to enforce this. Therefore, you should test
that validation action outputs are not added to the inputs of any actions in the
tests for Starlark rules. For example:

```python
load("@bazel_skylib//lib:unittest.bzl", "analysistest")

def _validation_outputs_test_impl(ctx):
  env = analysistest.begin(ctx)

  actions = analysistest.target_actions(env)
  target = analysistest.target_under_test(env)
  validation_outputs = target.output_groups._validation.to_list()
  for action in actions:
    for validation_output in validation_outputs:
      if validation_output in action.inputs.to_list():
        analysistest.fail(env,
            "%s is a validation action output, but is an input to action %s" % (
                validation_output, action))

  return analysistest.end(env)

validation_outputs_test = analysistest.make(_validation_outputs_test_impl)
```

#### Validation Actions Flag

Running validation actions is controlled by the `--run_validations` command line
flag, which defaults to true.

## Deprecated features

### Deprecated predeclared outputs

There are two **deprecated** ways of using predeclared outputs:

*   The [`outputs`](/rules/lib/globals/bzl#rule.outputs) parameter of `rule` specifies
    a mapping between output attribute names and string templates for generating
    predeclared output labels. Prefer using non-predeclared outputs and
    explicitly adding outputs to `DefaultInfo.files`. Use the rule target's
    label as input for rules which consume the output instead of a predeclared
    output's label.

*   For [executable rules](#executable-rules), `ctx.outputs.executable` refers
    to a predeclared executable output with the same name as the rule target.
    Prefer declaring the output explicitly, for example with
    `ctx.actions.declare_file(ctx.label.name)`, and ensure that the command that
    generates the executable sets its permissions to allow execution. Explicitly
    pass the executable output to the `executable` parameter of `DefaultInfo`.

### Runfiles features to avoid

[`ctx.runfiles`](/rules/lib/builtins/ctx#runfiles) and the [`runfiles`](/rules/lib/builtins/runfiles)
type have a complex set of features, many of which are kept for legacy reasons.
The following recommendations help reduce complexity:

*   **Avoid** use of the `collect_data` and `collect_default` modes of
    [`ctx.runfiles`](/rules/lib/builtins/ctx#runfiles). These modes implicitly collect
    runfiles across certain hardcoded dependency edges in confusing ways.
    Instead, add files using the `files` or `transitive_files` parameters of
    `ctx.runfiles`, or by merging in runfiles from dependencies with
    `runfiles = runfiles.merge(dep[DefaultInfo].default_runfiles)`.

*   **Avoid** use of the `data_runfiles` and `default_runfiles` of the
    `DefaultInfo` constructor. Specify `DefaultInfo(runfiles = ...)` instead.
    The distinction between "default" and "data" runfiles is maintained for
    legacy reasons. For example, some rules put their default outputs in
    `data_runfiles`, but not `default_runfiles`. Instead of using
    `data_runfiles`, rules should *both* include default outputs and merge in
    `default_runfiles` from attributes which provide runfiles (often
    [`data`](/reference/be/common-definitions#common-attributes.data)).

*   When retrieving `runfiles` from `DefaultInfo` (generally only for merging
    runfiles between the current rule and its dependencies), use
    `DefaultInfo.default_runfiles`, **not** `DefaultInfo.data_runfiles`.

### Migrating from legacy providers

Historically, Bazel providers were simple fields on the `Target` object. They
were accessed using the dot operator, and they were created by putting the field
in a [`struct`](/rules/lib/builtins/struct) returned by the rule's
implementation function instead of a list of provider objects:

```python
return struct(example_info = struct(headers = depset(...)))
```

Such providers can be retrieved from the corresponding field of the `Target` object:

```python
transitive_headers = [hdr.example_info.headers for hdr in ctx.attr.hdrs]
```

*This style is deprecated and should not be used in new code;* see following for
information that may help you migrate. The new provider mechanism avoids name
clashes. It also supports data hiding, by requiring any code accessing a
provider instance to retrieve it using the provider symbol.

For the moment, legacy providers are still supported. A rule can return both
legacy and modern providers as follows:

```python
def _old_rule_impl(ctx):
  ...
  legacy_data = struct(x = "foo", ...)
  modern_data = MyInfo(y = "bar", ...)
  # When any legacy providers are returned, the top-level returned value is a
  # struct.
  return struct(
      # One key = value entry for each legacy provider.
      legacy_info = legacy_data,
      ...
      # Additional modern providers:
      providers = [modern_data, ...])
```

If `dep` is the resulting `Target` object for an instance of this rule, the
providers and their contents can be retrieved as `dep.legacy_info.x` and
`dep[MyInfo].y`.

In addition to `providers`, the returned struct can also take several other
fields that have special meaning (and thus don't create a corresponding legacy
provider):

*   The fields `files`, `runfiles`, `data_runfiles`, `default_runfiles`, and
    `executable` correspond to the same-named fields of
    [`DefaultInfo`](/rules/lib/providers/DefaultInfo). It is not allowed to specify any of
    these fields while also returning a `DefaultInfo` provider.

*   The field `output_groups` takes a struct value and corresponds to an
    [`OutputGroupInfo`](/rules/lib/providers/OutputGroupInfo).

In [`provides`](/rules/lib/globals/bzl#rule.provides) declarations of rules, and in
[`providers`](/rules/lib/toplevel/attr#label_list.providers) declarations of dependency
attributes, legacy providers are passed in as strings and modern providers are
passed in by their `Info` symbol. Be sure to change from strings to symbols
when migrating. For complex or large rule sets where it is difficult to update
all rules atomically, you may have an easier time if you follow this sequence of
steps:

1.  Modify the rules that produce the legacy provider to produce both the legacy
    and modern providers, using the preceding syntax. For rules that declare they
    return the legacy provider, update that declaration to include both the
    legacy and modern providers.

2.  Modify the rules that consume the legacy provider to instead consume the
    modern provider. If any attribute declarations require the legacy provider,
    also update them to instead require the modern provider. Optionally, you can
    interleave this work with step 1 by having consumers accept or require either
    provider: Test for the presence of the legacy provider using
    `hasattr(target, 'foo')`, or the new provider using `FooInfo in target`.

3.  Fully remove the legacy provider from all rules.
