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

**Status: Experimental**. We may make breaking changes to the API, but we will
  help you update your code.

A rule defines a series of actions that Bazel should perform on inputs to get a
set of outputs.  For example, a C++ binary rule might take a set of .cpp
files (the inputs), run `g++` on them (the action), and return an executable
file (the output).

Note that, 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 (called _implicit inputs_).

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

See [the cookbook](cookbook.md#empty) for examples. The rule can then be
loaded by BUILD files:

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

A custom rule can be used just like a native rule. It has a mandatory `name`
attribute, you can refer to it with a label, and you can see it in
`bazel query`.

The rule is analyzed when you explicitly build it, or if it is a dependency of
the build. In this case, Bazel will execute its `implementation` function. This
function decides what the outputs of the rule are and how to build them (using
`actions`). During analysis, no external command can be executed: actions will
be run in the execution phase.

## Attributes

An attribute is a rule argument, such as `srcs` or `deps`. You must list
the attributes and their types when you define a rule.

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

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

Labels listed in `attr` will be inputs to the rule.

To access an attribute in a rule's implementation, use
`ctx.attr.<attribute_name>`. The name and the package of a rule are available
with `ctx.label.name` and `ctx.label.package`.

See [an example](cookbook.md#attr) of using `attr` in a rule.

### <a name="private-attributes"></a> Private Attributes

If an attribute name starts with `_` it is private and users cannot set it. It
is useful in particular for label attributes (your rule will have an
implicit dependency on this label).

```python
metal_compile = rule(
    implementation=impl,
    attrs={
        "srcs": attr.label_list(),
        "_compiler": attr.label(
            default=Label("//tools:metalc"),
            allow_single_file=True,
            executable=True,
        ),
    },
)
```

## Implementation function

Every rule requires an `implementation` function. It contains the actual
logic of the rule and is executed strictly in the Analysis Phase. The function
has exactly one input parameter, `ctx`, and it may return
the [runfiles](#runfiles) and [providers](#providers)
of the rule. The input parameter `ctx` can be used to access attribute values,
outputs and dependent targets, and files. It also has some helper functions.
See [the library](lib/ctx.html) for more context. Example:

```python
def impl(ctx):
  ...
  return struct(
      runfiles=...,
      my_provider=...,
      ...
  )

my_rule = rule(
    implementation=impl,
    ...
)
```

## Files

There are two kinds of files: files stored in the file system and generated
files. For each generated file, there must be one and only one generating
action, and each action must generate one or more output files. Bazel will throw
an error otherwise.

## Targets

Every build rule corresponds to exactly one target. A target can create
[actions](#actions), can have dependencies (which can be files or
other build rules), [output files](#output-files) (generated by
its actions), and [providers](#providers).

A target `y` depends on target `x` if `y` has a label or label list type
attribute where `x` is declared:

```python
my_rule(
    name = "x",
)

my_rule(
    name = "y",
    deps = [":x"],
)
```

In the above case, it's possible to access targets declared in `my_rule.deps`:

```python
def impl(ctx):
  for dep in ctx.attr.deps:
    # Do something with dep
  ...

my_rule = rule(
    implementation=impl,
    attrs={
        "deps": attr.label_list(),
    },
    ...
)
```

## <a name="output-files"></a> Output files

A target can declare output files, which must be generated by the target's
actions. There are three ways to create output files:

* If the rule is marked `executable`, it creates an output file of the same name
  as the rule's. [See example](cookbook.md#outputs-executable)

* The rule can declare default `outputs`, which are always generated.
  [See example](cookbook.md#outputs-default)

* The rule can have output or output list type attributes. In that case the
  output files come from the actual attribute values.
  [See example](cookbook.md#outputs-custom)

Each output file must have exactly one generating action. See the
[library](lib/ctx.html#outputs) for more context.

## Default outputs

Every rule has a set of default outputs. This is used:

* When the user runs `bazel build` on your target. Bazel will build the default
  outputs of the rule.

* When the target is used as a dependency of another rule. A rule can access
  the default outputs by using [target.files](lib/Target.html#files).
  This is the case, for example, if you use a rule in the `srcs` attribute of a
  `genrule`.

Use the `files` provider to specify the default outputs of a rule.
If left unspecified, it will contain all the declared outputs.

```python
def _impl(ctx):
  # ...
  return struct(files=set([file1, file2]))
```

This can be useful for exposing files generated with
[ctx.new_file](lib/ctx.html#new_file). You can also have "implicit
outputs", i.e., files that are declared in the rule, but not in the default
outputs (like `_deploy.jar` in `java_binary`).

## Actions

There are three ways to create actions:

* [ctx.action](lib/ctx.html#action), to run a command.
* [ctx.file_action](lib/ctx.html#file_action), to write a string to a file.
* [ctx.template_action](lib/ctx.html#template_action), 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. 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).

**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

By default, a target is built in the target configuration. For each label
attribute, you can decide whether the dependency should be built in the same
configuration, or in the host configuration.

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.

The configuration `"data"` is present for legacy reasons and should be used for
the `data` attributes.


## <a name="fragments"></a> Configuration Fragments

Rules may access configuration fragments 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 used to access information from other rules. A rule depending on
another rule has access to the data the latter provides. These data can be e.g.
output files, the libraries the dependent rule is using to link or compile, or
anything the depending rule should know about. Using providers is the only way
to exchange data between rules.

A rule can only access data provided by its direct dependencies, not that of
transitive dependencies: if rule `top` depends on `middle`, and `middle` depends
on `bottom`, then `middle` is a direct dependency of `top` and `bottom` is a
transitive dependency of `top`. In this scenario `top` can only access data
provided by `middle`. If `middle` also provides the data that `bottom` provided
to it, then and only then can `top` access it.

The following data types can be passed using providers:

* `bool`
* `integer`
* `string`
* `file`
* `label`
* `None`
* anything composed of these types and `lists`, `dicts`, `sets` or `structs`

Providers are created from the return value of the rule implementation function:

```python
def rule_implementation(ctx):
  ...
  return struct(
    transitive_data=set(["a", "b", "c"])
  )
```

A dependent rule might access these data as struct fields of the `target` being
depended upon:

```python
def dependent_rule_implementation(ctx):
  ...
  s = set()
  for dep_target in ctx.attr.deps:
    # Use `print(dir(dep_target))` to see the list of providers.
    s += dep_target.transitive_data
  ...
```

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

* [mandatory providers](cookbook.md#mandatory-providers)
* [optional providers](cookbook.md#optional-providers)

## 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 execution, Bazel creates a directory tree containing symlinks pointing to
the runfiles, staging the environment for the binary so it can access the
runfiles during runtime.

Runfiles can be added manually during rule creation and/or collected
transitively from the rule's dependencies:

```python
def rule_implementation(ctx):
  ...
  transitive_runfiles = set()
  for dep in ctx.attr.special_dependencies:
     transitive_runfiles += dep.transitive_runtime_files

  runfiles = ctx.runfiles(
      # Add some files manually.
      files=[ctx.file.some_data_file],
      # Add transitive files from dependencies manually.
      transitive_files=transitive_runfiles,
      # Collect runfiles from the common locations: transitively from srcs,
      # deps and data attributes.
      collect_default=True,
  )
  # Add a field named "runfiles" to the return struct in order to actually
  # create the symlink tree.
  return struct(runfiles=runfiles)
```

Note that 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.

Also note that if an action uses an executable, the executable's runfiles can
be used when the action executes.

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.

## Instrumented files

Instrumented files are a set of files used by the coverage command. A rule can
use the `instrumented_files` provider to provide information about which files
should be used for measuring coverage.

```python
def rule_implementation(ctx):
  ...
  return struct(instrumented_files=struct(
      # 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"]))
```

## Executable rules

An executable rule is a rule that users can run using `bazel run`.

To make a rule executable, set `executable=True` in the
[rule function](lib/globals.html#rule). During the analysis
phase, the rule must generate the output file `ctx.outputs.executable`.
[See example](cookbook.md#outputs-executable)

## Test rules

Test rules are run using `bazel test`.

To create a test rule, set `test=True` in the
[rule function](lib/globals.html#rule). The name of the rule must
also end with `_test`. Test rules are implicitly executable, which means they
must generate the output file `ctx.outputs.executable`.

Test rules inherit the following attributes: `args`, `flaky`, `local`,
`shard_count`, `size`, `timeout`.
