| --- | |
| title: 'Extension Overview' | |
| --- | |
| This page describes how to extend the BUILD language using macros | |
| and rules. | |
| Bazel extensions are files ending in `.bzl`. Use a | |
| [load statement](/versions/8.8.1/concepts/build-files#load) to import a symbol from an extension. | |
| Before learning the more advanced concepts, first: | |
| * Read about the [Starlark language](/versions/8.8.1/rules/language), used in both the | |
| `BUILD` and `.bzl` files. | |
| * Learn how you can [share variables](/versions/8.8.1/build/share-variables) | |
| between two `BUILD` files. | |
| ## Macros and rules | |
| A macro is a function that instantiates rules. Macros come in two flavors: | |
| [symbolic macros](/versions/8.8.1/extending/macros) (new in Bazel 8) and [legacy | |
| macros](/versions/8.8.1/extending/legacy-macros). The two flavors of macros are defined | |
| differently, but behave almost the same from the point of view of a user. A | |
| macro is useful when a `BUILD` file is getting too repetitive or too complex, as | |
| it lets you 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 *almost* as if you declared that `genrule` in the `BUILD` file. (The one | |
| exception is that targets declared in a symbolic macro have [special visibility | |
| semantics](/versions/8.8.1/extending/macros#visibility): a symbolic macro can hide its internal | |
| targets from the rest of the package.) | |
| A [rule](/versions/8.8.1/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; we recommend a symbolic | |
| macro, unless you need to support older Bazel versions. 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 | |
| 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](/versions/8.8.1/rules/macro-tutorial) in order to reuse some code. | |
| Then [learn more about macros](/versions/8.8.1/extending/macros) and [using them to create | |
| "custom verbs"](/versions/8.8.1/rules/verbs-tutorial). | |
| * [Follow the rules tutorial](/versions/8.8.1/rules/rules-tutorial) to get started with rules. | |
| Next, you can read more about the [rules concepts](/versions/8.8.1/extending/rules). | |
| The two links below will be very useful when writing your own extensions. Keep | |
| them within reach: | |
| * The [API reference](/versions/8.8.1/rules/lib) | |
| * [Examples](https://github.com/bazelbuild/examples/tree/master/rules) | |
| ## Going further | |
| In addition to [macros](/versions/8.8.1/extending/macros) and [rules](/versions/8.8.1/extending/rules), you | |
| may want to write [aspects](/versions/8.8.1/extending/aspects) and [repository | |
| rules](/versions/8.8.1/extending/repo). | |
| * Use [Buildifier](https://github.com/bazelbuild/buildtools) | |
| consistently to format and lint your code. | |
| * Follow the [`.bzl` style guide](/versions/8.8.1/rules/bzl-style). | |
| * [Test](/versions/8.8.1/rules/testing) your code. | |
| * [Generate documentation](https://skydoc.bazel.build/) to help your users. | |
| * [Optimize the performance](/versions/8.8.1/rules/performance) of your code. | |
| * [Deploy](/versions/8.8.1/rules/deploying) your extensions to other people. |