---
layout: documentation
title: Rules
---

# Rules

A **rule** defines a series of [**actions**](#actions) that Bazel performs on
inputs to produce a set of outputs. For example, a C++ binary rule might:

1. Take a set of `.cpp` files (the inputs)
2. Run `g++` on them (the action)
3. Return an executable file (the output).

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](concepts.md). It will be important to understand the three phases
of a build (loading, analysis and execution). It will also be useful to learn
about [macros](macros.md) to understand the difference between rules and macros.

A few rules are built into Bazel itself. These *native rules*, such as
`cc_library` and `java_binary`, provide some core support for certain languages.
By defining your own rules, you can add similar support for languages and tools
that Bazel does not support natively.

Bazel provides an extensibility model for writing rules using the
[Starlark](language.md) 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](concepts.md#evaluation-model). This function does not 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.

Rules also produce and pass along information that may be useful to other rules
in the form of [providers](#providers).

## Rule creation

In a `.bzl` file, use the [rule](lib/globals.html#rule)
function to create a new rule and store it in a global variable:

```python
my_rule = rule(...)
```

The rule can then be loaded in `BUILD` files:

```python
load('//some/pkg:whatever.bzl', 'my_rule')
```

[See example](https://github.com/bazelbuild/examples/tree/master/rules/empty).

## Attributes

An attribute is a rule argument, such as `srcs` or `deps`. You must list the
names and schemas of all attributes when you define a rule. Attribute schemas
are created using the [attr](lib/attr.html) module.

```python
sum = rule(
    implementation = _impl,
    attrs = {
        "number": attr.int(default = 1),
        "deps": attr.label_list(),
    },
)
```

In a `BUILD` file, call the rule to create targets of this type:

```python
sum(
    name = "my-target",
    deps = [":other-target"],
)

sum(
    name = "other-target",
)
```

Here `other-target` is a dependency of `my-target`, and therefore `other-target`
will be analyzed first.

There are two special kinds of attributes:

* *Dependency attributes*, such as `attr.label` and `attr.label_list`,
  declare a dependency from the target that owns the attribute to the target
  whose label appears in the attribute's value. This kind of attribute forms the
  basis of the target graph.

* *Output attributes*, such as `attr.output` and `attr.output_list`, declare an
  output file that the target generates. Although they refer to the output file
  by label, they do not create a dependency relationship between targets. Output
  attributes are used relatively rarely, in favor of other ways of declaring
  output files that do not require the user to specify a label.

Both dependency attributes and output attributes take in label values. These may
be specified as either [`Label`](lib/Label.html) objects or as simple strings.
If a string is given, it will be converted to a `Label` using the
[constructor](lib/Label.html#Label). The repository, and possibly the path, will
be resolved relative to the defined target.

If an attribute schema is defined in the rule but no value for that attribute is
given when the rule is instantiated, then the rule implementation function will
see a placeholder value in `ctx.attr`. The placeholder value depends on the type
of attribute. If the schema specifies a `default` value, that value will be used
instead of the placeholder. The schema may also specify `mandatory=True`, in
which case it is illegal for the user to not give an explicit value. It is not
useful for an attribute schema with `mandatory` to also have a `default`.

The following attributes are automatically added to every rule: `deprecation`,
`features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the
following attributes: `args`, `flaky`, `local`, `shard_count`, `size`,
`timeout`.

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

### Private attributes and implicit dependencies

A dependency attribute with a default value is called an *implicit dependency*.
The name comes from the fact that it is a part of the target graph that the user
does not specify in a BUILD file. Implicit dependencies are useful for
hard-coding a relationship between a rule and a tool (such as a compiler), since
most of the time a user is not interested in specifying what tool the rule uses.
From the rule's point of view, the tool is still an input, just like any source
file or other dependency.

Sometimes we want to not only provide a default value, but prevent the user from
overriding this default. To do this, 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
metal_binary = rule(
    implementation = _metal_binary_impl,
    attrs = {
        "srcs": attr.label_list(),
        "_compiler": attr.label(
            default = Label("//tools:metalc"),
            allow_single_file = True,
            executable = True,
        ),
    },
)
```

In this example, every target of type `metal_binary` will have an implicit
dependency on the compiler `//tools:metalc`. This allows `metal_binary`'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, we know for sure that `ctx.attr._compiler` will always point
to `//tools:metalc` in all targets of this rule type. Alternatively, we could
have named the attribute `compiler` without the underscore and kept the default
value. This lets users substitute a different compiler if necessary, but
requires no awareness of the compiler's label otherwise.

## Implementation function

Every rule requires an `implementation` function. This function contains the
actual logic of the rule and is executed strictly in the
[analysis phase](concepts.md#evaluation-model). As such, the function is not
able to actually read or write files. Rather, its main job is to emit
[actions](#actions) that will run later during the execution phase.

Implementation functions take exactly one parameter: a [rule
context](lib/ctx.html), conventionally named `ctx`. It can be used to:

* access attribute values and obtain handles on declared input and output files;

* create actions; and

* pass information to other targets that depend on this one, via
  [providers](#providers).

The most common way to access attribute values is by using
`ctx.attr.<attribute_name>`, though there are several other fields besides
`attr` that provide more convenient ways of accessing file handles, such as
`ctx.file` and `ctx.outputs`. The name and the package of a rule are available
with `ctx.label.name` and `ctx.label.package`. The `ctx` object also contains
some helper functions. See its [documentation](lib/ctx.html) for a complete
list.

Rule implementation functions are usually private (i.e., named with a leading
underscore) because they tend not to be reused. Conventionally, they are named
the same as their rule, but suffixed with `_impl`.

See [an example](https://github.com/bazelbuild/examples/blob/master/rules/attributes/printer.bzl)
of declaring and accessing attributes.

## Targets

Each call to a build rule returns no value but has the side effect of defining a
new target; this is called instantiating the rule. The dependencies of the new
target are any other targets whose labels are mentioned in its dependency
attributes. In the following example, the target `//mypkg:y` depends on the
targets `//mypkg:x` and `//mypkg:z.foo`.

```python
# //mypkg:BUILD

my_rule(
    name = "x",
)

# Assuming that my_rule has attributes "deps" and "srcs",
# of type attr.label_list()
my_rule(
    name = "y",
    deps = [":x"],
    srcs = [":z.foo"],
)
```

Dependencies are represented at analysis time as [`Target`](lib/Target.html)
objects. These objects contain the information produced by analyzing a target --
in particular, its [providers](#providers). The current target can access its
dependencies' `Target` objects within its rule implementation function by using
`ctx.attr`.

## Files

Files are represented by the [`File`](lib/File.html) type. Since Bazel does not
perform file I/O during the analysis phase, these objects cannot be used to
directly read or write file content. Rather, they are passed to action-emitting
functions to construct pieces of the action graph. See
[`ctx.actions`](lib/actions.html) for the available kinds of actions.

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 cannot be the output of any
action.

Some files, including all source files, are addressable by labels. These files
have `Target` objects associated with them. If a file's label appears within a
dependency attribute (for example, in a `srcs` attribute of type
`attr.label_list`), the `ctx.attr.<attr_name>` entry for it will contain the
corresponding `Target`. The `File` object can be obtained from this `Target`'s
`files` field. This allows the file to be referenced in both the target graph
and the action graph.

### Outputs

A generated file that is addressable by a label is called a *predeclared
output*. Rules can specify predeclared outputs via
[`output`](lib/attr.html#output) or [`output_list`](lib/attr.html#output_list)
attributes. In that case, the user explicitly chooses labels for outputs when
they instantiate the rule. To obtain file objects for output attributes, use
the corresponding attribute of [`ctx.outputs`](lib/ctx.html#outputs).

During the analysis phase, a rule's implementation function can create
additional outputs. Since all labels have to be known during the loading phase,
these additional outputs have no labels. Non-predeclared outputs are created
using [`ctx.actions.declare_file`](lib/actions.html#declare_file),
[`ctx.actions.write`](lib/actions.html#write), and
[`ctx.actions.declare_directory`](lib/actions.html#declare_directory).

All outputs can be passed along in [providers](#providers) to make them
available to a target's consumers, whether or not they have a label. A target's
*default outputs* are specified by the `files` parameter of
[`DefaultInfo`](lib/DefaultInfo.html). If `DefaultInfo` is not returned by a
rule implementation or the `files` parameter is not specified,
`DefaultInfo.files` defaults to all *predeclared* outputs.

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

*   The [`outputs`](lib/globals.html#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-and-test-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`.

[See example of predeclared outputs](https://github.com/bazelbuild/examples/blob/master/rules/predeclared_outputs/hash.bzl)

## 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 (e.g. in C,
the linker must be called after compilation). In the execution phase, Bazel
decides which actions must be run and in which order.

All functions that create actions are defined in [`ctx.actions`](lib/actions.html):

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

Actions take a set (which can be empty) of input files and generate a (non-empty)
set of output files.
The set of input and output files must be known during the
[analysis phase](concepts.md#evaluation-model). It might depend on the value
of attributes and information from dependencies, but it cannot 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 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.

**If an action generates a file that is not listed in its outputs**: This is
fine, but the file will be ignored and cannot be used by other rules.

**If an action does not generate a file that is listed in its outputs**: This is
an execution error and the build will fail. This happens for instance when a
compilation fails.

**If an action generates an unknown number of outputs and you want to keep them
all**, you must group them in a single file (e.g., a zip, tar, or other
archive format). This way, you will be able to deterministically declare your
outputs.

**If an action does not list a file it uses as an input**, the action execution
will most likely result in an error. The file is not guaranteed to be available
to the action, so if it **is** there, it's due to coincidence or error.

**If an action lists a file as an input, but does not use it**: This is fine.
However, it can affect action execution order, resulting in sub-optimal
performance.

Dependencies are resolved by Bazel, which will decide which actions are
executed. It is an error if there is a cycle in the dependency graph. Creating
an action does not guarantee that it will be executed: It depends on whether
its outputs are needed for the build.

## 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 your machine (the
host). 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 locally on the host are
built in the "host" 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 the host configuration. This causes the tool and all its
dependencies to build for the host machine.

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

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 (e.g., compilers, code generators)
should be built for the host configuration. In this case, specify `cfg="host"`
in the attribute.

Otherwise, executables that are used at runtime (e.g. 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.

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

## Configuration fragments

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

```python
def _impl(ctx):
    # Using ctx.fragments.cpp would lead 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
    host_fragments = ["java"], # Required fragments of the host configuration
    ...
)
```

`ctx.fragments` only provides configuration fragments for the target
configuration. If you want to access fragments for the host configuration,
use `ctx.host_fragments` instead.

## 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 the depending rule should know about.
Providers are the only mechanism to exchange data between rules, and can be
thought of as part of a rule's public interface (loosely analogous to a
function's return value).

A rule can only see the providers of its direct dependencies. If there is a rule
`top` that depends on `middle`, and `middle` depends on `bottom`, then we say
that `middle` is a direct dependency of `top`, while `bottom` is a transitive
dependency of `top`. In this case, `top` can see the providers of `middle`. The
only way for `top` to see any information from `bottom` is if `middle`
re-exports this information in its own providers; this is how transitive
information can be accumulated from all dependencies. In such cases, consider
using [depsets](depsets.md) to hold the data more efficiently without excessive
copying.

Providers can be declared using the [provider()](lib/globals.html#provider) function:

```python
TransitiveDataInfo = provider(fields=["value"])
```

Rule implementation function can then construct and return provider instances:

```python
def rule_implementation(ctx):
  ...
  return [TransitiveDataInfo(value=5)]
```

`TransitiveDataInfo` acts both as a constructor for provider instances and as a key to access them.
A [target](lib/Target.html) serves as a map from each provider that the target supports, to the
target's corresponding instance of that provider.
A rule can access the providers of its dependencies using the square bracket notation (`[]`):

```python
def dependent_rule_implementation(ctx):
  ...
  n = 0
  for dep_target in ctx.attr.deps:
    n += dep_target[TransitiveDataInfo].value
  ...
```

All targets have a [`DefaultInfo`](lib/DefaultInfo.html) provider that can be used to access
some information relevant to all targets.

Providers are only available during the analysis phase. Examples of usage:

* [mandatory providers](https://github.com/bazelbuild/examples/blob/master/rules/mandatory_provider/sum.bzl)
* [optional providers](https://github.com/bazelbuild/examples/blob/master/rules/optional_provider/sum.bzl)
* [providers with depsets](https://github.com/bazelbuild/examples/blob/master/rules/depsets/foo.bzl)
    This examples shows how a library and a binary rule can pass information.

### 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 returned by the rule's implementation function.

*This style is deprecated and should not be used in new code;* see below 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 _myrule_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,
      ...
      # All modern providers are put in a list passed to the special "providers" key.
      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 that do not create a corresponding legacy
provider).

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

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

In [`provides`](lib/globals.html#rule.provides) declarations of rules, and in
[`providers`](lib/attr.html#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 above 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/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.

## Runfiles

Runfiles are a set of files used by the (often executable) output of a rule
during runtime (as opposed to build time, i.e. when the binary itself is
generated). During the
[execution phase](concepts.md#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`](lib/runfiles.html) objects can be created by the `runfiles` method
on the rule context, [`ctx.runfiles`](lib/ctx.html#runfiles).

### Basic usage

Use `runfiles` objects to specify a set of files that are needed in an
executable's environment at runtime. Do this by passing a `runfiles` object to
the `runfiles` parameter of the `DefaultInfo` object returned by your rule.

Construct `runfiles` objects using `ctx.runfiles` with parameters
`files` and `transitive_files`.

Example:

```python
def _rule_implementation(ctx):
  ...
  runfiles = ctx.runfiles(
      files = [ctx.file.some_data_file],
      transitive_files = ctx.attr.something[SomeProviderInfo].depset_of_files,
  )

  return [DefaultInfo(runfiles=runfiles)]
```

The specified `files` and `transitive_files` will be available to the
executable's runtime environment. The location of these files relative to
the execution root may be obtained in a couple of ways. **Note that the
following recommendations only work for obtaining relative runfiles paths
when running an executable on the command line with `bazel run`**:

* If relevant files are themselves valid targets (and thus have a corresponding
label), you may use [`ctx.expand_location`](lib/ctx.html#expand_location).
* Use [`file.short_path`](lib/File.html#short_path).

See [basic example](https://github.com/bazelbuild/examples/blob/master/rules/runfiles/execute.bzl).

### Libraries with runfiles

Non-executable rule outputs can also have runfiles. For example, a
library might need some external files during runtime, and every dependent
binary should know about them. In such cases, it's recommended to propagate
these files via a custom provider; propagate the files themselves via a
`depset`; avoid propagating the `runfiles` object type in anything other than
`DefaultInfo`, as it generally adds unnecessary complexity. (There are
exceptions listed later!)

See [example](https://github.com/bazelbuild/examples/blob/master/rules/runfiles/library.bzl).

### Tools with runfiles

A build action might use an executable that requires runfiles (such executables
are nicknamed "tools"). For such cases, depend on this executable target
via an attribute which has `executable = True` specified. The executable file
will then be available under `ctx.executable.<attr_name>`. By passing this file
to the `executable` parameter of the action registration function, the
executable's runfiles will be implicitly added to the execution environment.

The runfiles directory structure for tools is different than for basic
executables (executables simply run with `bazel run`).

* The tool executable file exists in a root-relative path derived from its
label. This full relative path can be obtained via
`ctx.executable.<attr_name>.path`.
* The runfiles for the tool exist in a `.runfiles` directory which resides
adjacent to the tool's path. An individual runfile can thus be found at the
following path relative to the execution root.

```python
# Given executable_file and runfile_file:
runfiles_root = executable_file.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)
```

See [example](https://github.com/bazelbuild/examples/blob/master/rules/runfiles/tool.bzl).

### 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 workspace.

```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!

### Tools depending on tools

A tool (executable used for action registration) may depend on another
tool with its own runfiles. (For purposes of this explanation, we nickname
the primary tool the "root tool" and the tool it depends on a "subtool".)

Merge the runfiles of subtools with the root tool by using
[`runfiles.merge`](lib/runfiles.html#merge). Acquire the runfiles of subtools
via [`DefaultInfo.default_runfiles`](lib/DefaultInfo.html#default_runfiles)

Example code:

```python
def _mytool_impl(ctx):
  ...
  my_runfiles = ctx.runfiles(files = mytool_files)
  for subtool in ctx.attr.subtools:
    subtool_runfiles = subtool[DefaultInfo].default_runfiles
    my_runfiles = my_runfiles.merge(subtool_runfiles)
  ...
  return [DefaultInfo(runfiles = my_runfiles))]
```

The runfiles directory structure is a bit more difficult to manage for
subtools. The runfiles directory is always adjacent to the *root* tool being
run -- not an individual subtool. To simplify subtool tool logic, it's
recommended that each subtool optionally accept its runfiles root as a
parameter (via environment or command line argument/flag). A root tool can thus
pass the correct canonical runfiles root to any of its subtools.

This scenario is complex and thus best demonstrated by
[an example](https://github.com/bazelbuild/examples/blob/master/rules/runfiles/complex_tool.bzl).

### Runfiles features to avoid

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

* **Avoid** use of the `collect_data` and `collect_default` modes of
[`ctx.runfiles`](lib/ctx.html#runfiles). These modes implicitly collect runfiles
across certain hardcoded dependency edges in confusing ways. Instead, manually
collect files along relevant dependency edges and add them to your runfiles
using `files` or `transitive_files` parameters of `ctx.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, but
is unimportant for new usage.
* 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`.

## 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.)

Every target has a set of *default outputs*, which are the output files that
normally get requested when that target appears on the command line. For
example, a target `//pkg:foo` of `java_library` type has in its default outputs
a file `foo.jar`, which will be built by the command `bazel build //pkg:foo`.

Any predeclared output can be explicitly requested on the command line. This can
be used to build outputs that are not default outputs, or to build some but not
all default outputs. For example, `bazel build //pkg:foo_deploy.jar` and
`bazel build //pkg:foo.jar` will each just build that one file (along with
its dependencies). See an [example](https://github.com/bazelbuild/examples/blob/master/rules/implicit_output/hash.bzl)
of a rule with non-default predeclared outputs.

In addition to default outputs, there are *output groups*, which are collections
of output files that may be requested together. 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`. See the [command line
reference](../command-line-reference.html#flag--output_groups)
for details on the `--output_groups` argument. Since non-predeclared outputs
don't have labels, they can only be requested by appearing in the default
outputs or an output group.

You can specify the default outputs and output groups of a rule by returning the
[`DefaultInfo`](lib/DefaultInfo.html) and
[`OutputGroupInfo`](lib/OutputGroupInfo.html) providers from its implementation
function.

```python
def _myrule_impl(ctx):
  name = ...
  binary = ctx.actions.declare_file(name)
  debug_file = ctx.actions.declare_file(name + ".pdb")
  # ... add actions to generate these files
  return [DefaultInfo(files = depset([binary])),
          OutputGroupInfo(debug_files = depset([debug_file]),
                          all_files = depset([binary, debug_file]))]
```

These providers can also be retrieved from dependencies using the usual syntax
`<target>[DefaultInfo]` and `<target>[OutputGroupInfo]`, where `<target>` is a
`Target` object.

Note that even if a file is in the default outputs or an output group, you may
still want to return it in a custom provider in order to make it available in a
more structured way. For instance, you could pass headers and sources along in
separate fields of your provider.

## Code coverage instrumentation

A rule can use the `InstrumentedFilesInfo` provider to provide information about
which files should be measured when code coverage data collection is enabled.
That provider can be created with
[`coverage_common.instrumented_files_info`](lib/coverage_common.html#instrumented_files_info)
and included in the list of providers returned by the rule's implementation
function:

```python
def _rule_implementation(ctx):
  ...
  instrumented_files_info = coverage_common.instrumented_files_info(
      ctx,
      # Optional: File extensions used to filter files from source_attributes.
      # If not provided, then all files from source_attributes will be
      # added to instrumented files, if an empty list is provided, then
      # no files from source attributes will be added.
      extensions = ["ext1", "ext2"],
      # Optional: Attributes that contain source files for this rule.
      source_attributes = ["srcs"],
      # Optional: Attributes for dependencies that could include instrumented
      # files.
      dependency_attributes = ["data", "deps"])
  return [..., instrumented_files_info]
```

[ctx.configuration.coverage_enabled](lib/configuration.html#coverage_enabled) notes
whether coverage data collection is enabled for the current run in general
(but says nothing about which files specifically should be instrumented).
If a rule implementation needs to add coverage instrumentation at
compile-time, it can determine if its sources should be instrumented with
[ctx.coverage_instrumented](lib/ctx.html#coverage_instrumented):

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

Note that function will always return false if `ctx.configuration.coverage_enabled` is
false, so you don't need to check both.

If the rule directly includes sources from its dependencies before compilation
(e.g. header files), it may also need to turn on compile-time instrumentation
if the dependencies' sources should be instrumented. In this case, it may
also be worth checking `ctx.configuration.coverage_enabled` so you can avoid looping
over dependencies unnecessarily:

```python
# Are this rule's sources or any of the sources for its direct dependencies
# in deps instrumented?
if ctx.configuration.coverage_enabled:
    if (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
```

## 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`](lib/globals.html#rule.executable) or
[`test`](lib/globals.html#rule.test) argument to true when defining the rule.

Test rules (but not necessarily their targets) must have names that end in
`_test`. 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`](lib/DefaultInfo.html)
provider.

The action that generates this file must set the executable bit on the file. For
a `ctx.actions.run()` or `ctx.actions.run_shell()` action this should be done by
the underlying tool that is invoked by the action. For a `ctx.actions.write()`
action it is done by passing the argument `is_executable=True`.

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

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

Test rules inherit the following attributes: `args`, `flaky`, `local`,
`shard_count`, `size`, `timeout`. The defaults of inherited attributes cannot be
changed, but you can use a macro with default arguments:

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

_example_test = rule(
 ...
)
```
