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

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

## Rule creation

In a Skylark extension, use the [rule](lib/globals.html#rule) function
to create a new rule and store it in a global variable.
[See example](cookbook.md#empty).

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

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

[See example.](cookbook.md#attr)

### <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"),
            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 in Skylark:

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

All output files 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 may group them in a zip file. This way, you will be able to declare
your output.

**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_CFG`
in the attribute.

`DATA_CFG` is present for legacy reasons and should be used for `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`.
