| Project: /_project.yaml |
| Book: /_book.yaml |
| |
| # Extension Overview |
| |
| {% include "_buttons.html" %} |
| |
| <!-- [TOC] --> |
| |
| This page describes how to extend the BUILD language using macros |
| and rules. |
| |
| Bazel extensions are files ending in `.bzl`. Use a |
| [load statement](/concepts/build-files#load) to import a symbol from an extension. |
| |
| Before learning the more advanced concepts, first: |
| |
| * Read about the [Starlark language](/rules/language), used in both the |
| `BUILD` and `.bzl` files. |
| |
| * Learn how you can [share variables](/build/share-variables) |
| between two `BUILD` files. |
| |
| ## Macros and rules |
| |
| A [macro](/extending/macros) is a function that instantiates rules. It is useful when a |
| `BUILD` file is getting too repetitive or too complex, as it allows you to reuse |
| some code. The function is evaluated as soon as the `BUILD` file is read. After |
| the evaluation of the `BUILD` file, Bazel has little information about macros: |
| if your macro generates a `genrule`, Bazel will behave as if you wrote the |
| `genrule`. As a result, `bazel query` will only list the generated `genrule`. |
| |
| A [rule](/extending/rules) is more powerful than a macro. It can access Bazel |
| internals and have full control over what is going on. It may for example pass |
| information to other rules. |
| |
| If you want to reuse simple logic, start with a macro. If a macro becomes |
| complex, it is often a good idea to make it a rule. Support for a new language |
| is typically done with a rule. Rules are for advanced users, and most |
| users will never have to write one; they will only load and call existing |
| rules. |
| |
| ## Evaluation model {:#evaluation-model} |
| |
| A build consists of three phases. |
| |
| * **Loading phase**. First, load and evaluate all extensions and all `BUILD` |
| files that are needed for the build. The execution of the `BUILD` files simply |
| instantiates rules (each time a rule is called, it gets added to a graph). |
| This is where macros are evaluated. |
| |
| * **Analysis phase**. The code of the rules is executed (their `implementation` |
| function), and actions are instantiated. An action describes how to generate |
| a set of outputs from a set of inputs, such as "run gcc on hello.c and get |
| hello.o". You must list explicitly which files will be generated before |
| executing the actual commands. In other words, the analysis phase takes |
| the graph generated by the loading phase and generates an action graph. |
| |
| * **Execution phase**. Actions are executed, when at least one of their outputs is |
| required. If a file is missing or if a command fails to generate one output, |
| the build fails. Tests are also run during this phase. |
| |
| Bazel uses parallelism to read, parse and evaluate the `.bzl` files and `BUILD` |
| files. A file is read at most once per build and the result of the evaluation is |
| cached and reused. A file is evaluated only once all its dependencies (`load()` |
| statements) have been resolved. By design, loading a `.bzl` file has no visible |
| side-effect, it only defines values and functions. |
| |
| Bazel tries to be clever: it uses dependency analysis to know which files must |
| be loaded, which rules must be analyzed, and which actions must be executed. For |
| example, if a rule generates actions that you don't need for the current build, |
| they will not be executed. |
| |
| ## Creating extensions |
| |
| * [Create your first macro](/rules/macro-tutorial) in order to |
| reuse some code. Then [learn more about macros](/extending/macros) and |
| [using them to create "custom verbs"](/rules/verbs-tutorial). |
| |
| * [Follow the rules tutorial](/rules/rules-tutorial) to get started with rules. |
| Next, you can read more about the [rules concepts](/extending/rules). |
| |
| The two links below will be very useful when writing your own extensions. Keep |
| them within reach: |
| |
| * The [API reference](/rules/lib) |
| |
| * [Examples](https://github.com/bazelbuild/examples/tree/master/rules) |
| |
| ## Going further |
| |
| In addition to [macros](/extending/macros) and [rules](/extending/rules), you may want to write |
| [aspects](/extending/aspects) and [repository rules](/extending/repo). |
| |
| * Use [Buildifier](https://github.com/bazelbuild/buildtools){: .external} |
| consistently to format and lint your code. |
| |
| * Follow the [`.bzl` style guide](/rules/bzl-style). |
| |
| * [Test](/rules/testing) your code. |
| |
| * [Generate documentation](https://skydoc.bazel.build/) to help your users. |
| |
| * [Optimize the performance](/rules/performance) of your code. |
| |
| * [Deploy](/rules/deploying) your extensions to other people. |