---
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 explictly 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
dependened 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`.
