| --- | |
| title: 'Labels' | |
| --- | |
| A **label** is an identifier for a target. A typical label in its full canonical | |
| form looks like: | |
| ```none | |
| @@myrepo//my/app/main:app_binary | |
| ``` | |
| The first part of the label is the repository name, `@@myrepo`. The double-`@` | |
| syntax signifies that this is a [*canonical* repo | |
| name](/versions/9.2.0/external/overview#canonical-repo-name), which is unique within | |
| the workspace. Labels with canonical repo names unambiguously identify a target | |
| no matter which context they appear in. | |
| Often the canonical repo name is an arcane string that looks like | |
| `@@rules_java++toolchains+local_jdk`. What is much more commonly seen is | |
| labels with an [*apparent* repo name](/versions/9.2.0/external/overview#apparent-repo-name), | |
| which looks like: | |
| ``` | |
| @myrepo//my/app/main:app_binary | |
| ``` | |
| The only difference is the repo name being prefixed with one `@` instead of two. | |
| This refers to a repo with the apparent name `myrepo`, which could be different | |
| based on the context this label appears in. | |
| In the typical case that a label refers to the same repository from which | |
| it is used, the repo name part may be omitted. So, inside `@@myrepo` the first | |
| label is usually written as | |
| ``` | |
| //my/app/main:app_binary | |
| ``` | |
| The second part of the label is the un-qualified package name | |
| `my/app/main`, the path to the package | |
| relative to the repository root. Together, the repository name and the | |
| un-qualified package name form the fully-qualified package name | |
| `@@myrepo//my/app/main`. When the label refers to the same | |
| package it is used in, the package name (and optionally, the colon) | |
| may be omitted. So, inside `@@myrepo//my/app/main`, | |
| this label may be written either of the following ways: | |
| ``` | |
| app_binary | |
| :app_binary | |
| ``` | |
| It is a matter of convention that the colon is omitted for files, | |
| but retained for rules, but it is not otherwise significant. | |
| The part of the label after the colon, `app_binary` is the un-qualified target | |
| name. When it matches the last component of the package path, it, and the | |
| colon, may be omitted. So, these two labels are equivalent: | |
| ``` | |
| //my/app/lib | |
| //my/app/lib:lib | |
| ``` | |
| The name of a file target in a subdirectory of the package is the file's path | |
| relative to the package root (the directory containing the `BUILD` file). So, | |
| this file is in the `my/app/main/testdata` subdirectory of the repository: | |
| ``` | |
| //my/app/main:testdata/input.txt | |
| ``` | |
| Strings like `//my/app` and `@@some_repo//my/app` have two meanings depending on | |
| the context in which they are used: when Bazel expects a label, they mean | |
| `//my/app:app` and `@@some_repo//my/app:app`, respectively. But, when Bazel | |
| expects a package (e.g. in `package_group` specifications), they reference the | |
| package that contains that label. | |
| A common mistake in `BUILD` files is using `//my/app` to refer to a package, or | |
| to *all* targets in a package--it does not. Remember, it is | |
| equivalent to `//my/app:app`, so it names the `app` target in the `my/app` | |
| package of the current repository. | |
| However, the use of `//my/app` to refer to a package is encouraged in the | |
| specification of a `package_group` or in `.bzl` files, because it clearly | |
| communicates that the package name is absolute and rooted in the top-level | |
| directory of the workspace. | |
| Relative labels cannot be used to refer to targets in other packages; the | |
| repository identifier and package name must always be specified in this case. | |
| For example, if the source tree contains both the package `my/app` and the | |
| package `my/app/testdata` (each of these two directories has its own | |
| `BUILD` file), the latter package contains a file named `testdepot.zip`. Here | |
| are two ways (one wrong, one correct) to refer to this file within | |
| `//my/app:BUILD`: | |
| <p><span class="compare-worse">Wrong</span> — <code>testdata</code> is a different package, so you can't use a relative path</p> | |
| ``` | |
| testdata/testdepot.zip | |
| ``` | |
| <p><span class="compare-better">Correct</span> — refer to <code>testdata</code> with its full path</p> | |
| ``` | |
| //my/app/testdata:testdepot.zip | |
| ``` | |
| Labels starting with `@@//` are references to the main | |
| repository, which will still work even from external repositories. | |
| Therefore `@@//a/b/c` is different from | |
| `//a/b/c` when referenced from an external repository. | |
| The former refers back to the main repository, while the latter | |
| looks for `//a/b/c` in the external repository itself. | |
| This is especially relevant when writing rules in the main | |
| repository that refer to targets in the main repository, and will be | |
| used from external repositories. | |
| For information about the different ways you can refer to targets, see | |
| [target patterns](/versions/9.2.0/run/build#specifying-build-targets). | |
| ### Lexical specification of a label {#labels-lexical-specification} | |
| Label syntax discourages use of metacharacters that have special meaning to the | |
| shell. This helps to avoid inadvertent quoting problems, and makes it easier to | |
| construct tools and scripts that manipulate labels, such as the | |
| [Bazel Query Language](/versions/9.2.0/query/language). | |
| The precise details of allowed target names are below. | |
| ### Target names — `<var>package-name</var>:target-name` {#target-names} | |
| `target-name` is the name of the target within the package. The name of a rule | |
| is the value of the `name` attribute in the rule's declaration in a `BUILD` | |
| file; the name of a file is its pathname relative to the directory containing | |
| the `BUILD` file. | |
| Target names must be composed entirely of characters drawn from the set `a`–`z`, | |
| `A`–`Z`, `0`–`9`, and the punctuation symbols `!%-@^_"#$&'()*-+,;<=>?[]{|}~/.`. | |
| Filenames must be relative pathnames in normal form, which means they must | |
| neither start nor end with a slash (for example, `/foo` and `foo/` are | |
| forbidden) nor contain multiple consecutive slashes as path separators | |
| (for example, `foo//bar`). Similarly, up-level references (`..`) and | |
| current-directory references (`./`) are forbidden. | |
| <p><span class="compare-worse">Wrong</span> — Do not use <code>..</code> to refer to files in other packages</p> | |
| <p><span class="compare-better">Correct</span> — Use | |
| <code>//<var>package-name</var>:<var>filename</var></code></p> | |
| While it is common to use `/` in the name of a file target, avoid the use of | |
| `/` in the names of rules. Especially when the shorthand form of a label is | |
| used, it may confuse the reader. The label `//foo/bar/wiz` is always a shorthand | |
| for `//foo/bar/wiz:wiz`, even if there is no such package `foo/bar/wiz`; it | |
| never refers to `//foo:bar/wiz`, even if that target exists. | |
| However, there are some situations where use of a slash is convenient, or | |
| sometimes even necessary. For example, the name of certain rules must match | |
| their principal source file, which may reside in a subdirectory of the package. | |
| ### Package names — `//package-name:<var>target-name</var>` {#package-names} | |
| The name of a package is the name of the directory containing its `BUILD` file, | |
| relative to the top-level directory of the containing repository. | |
| For example: `my/app`. | |
| On a technical level, Bazel enforces the following: | |
| * Allowed characters in package names are the lowercase letters `a` through `z`, | |
| the uppercase letters `A` through `Z`, the digits `0` through `9`, the | |
| characters ``! \"#$%&'()*+,-.;<=>?@[]^_`{|}`` (yes, there's a space character | |
| in there!), and of course forward slash `/` (since it's the directory | |
| separator). | |
| * Package names may not start or end with a forward slash character `/`. | |
| * Package names may not contain the substring `//`. This wouldn't make | |
| sense---what would the corresponding directory path be? | |
| * Package names may not contain the substring `/./` or `/../` or `/.../` etc. | |
| This enforcement is done to avoid confusion when translating between a logical | |
| package name and a physical directory name, given the semantic meaning of the | |
| dot character in path strings. | |
| On a practical level: | |
| * For a language with a directory structure that is significant to its module | |
| system (for example, Java), it's important to choose directory names that are | |
| valid identifiers in the language. For example, don't start with a leading | |
| digit and avoid special characters, especially underscores and hyphens. | |
| * Although Bazel supports targets in the workspace's root package (for example, | |
| `//:foo`), it's best to leave that package empty so all meaningful packages | |
| have descriptive names. | |
| ## Rules {#rules} | |
| A rule specifies the relationship between inputs and outputs, and the | |
| steps to build the outputs. Rules can be of one of many different | |
| kinds (sometimes called the _rule class_), which produce compiled | |
| executables and libraries, test executables and other supported | |
| outputs as described in the [Build Encyclopedia](/versions/9.2.0/reference/be/overview). | |
| `BUILD` files declare _targets_ by invoking _rules_. | |
| In the example below, we see the declaration of the target `my_app` | |
| using the `cc_binary` rule. | |
| ```python | |
| cc_binary( | |
| name = "my_app", | |
| srcs = ["my_app.cc"], | |
| deps = [ | |
| "//absl/base", | |
| "//absl/strings", | |
| ], | |
| ) | |
| ``` | |
| Every rule invocation has a `name` attribute (which must be a valid | |
| [target name](#target-names)), that declares a target within the package | |
| of the `BUILD` file. | |
| Every rule has a set of _attributes_; the applicable attributes for a given | |
| rule, and the significance and semantics of each attribute are a function of | |
| the rule's kind; see the [Build Encyclopedia](/versions/9.2.0/reference/be/overview) for a | |
| list of rules and their corresponding attributes. Each attribute has a name and | |
| a type. Some of the common types an attribute can have are integer, label, list | |
| of labels, string, list of strings, output label, list of output labels. Not | |
| all attributes need to be specified in every rule. Attributes thus form a | |
| dictionary from keys (names) to optional, typed values. | |
| The `srcs` attribute present in many rules has type "list of labels"; its | |
| value, if present, is a list of labels, each being the name of a target that is | |
| an input to this rule. | |
| In some cases, the name of the rule kind is somewhat arbitrary, and more | |
| interesting are the names of the files generated by the rule, and this is true | |
| of genrules. For more information, see | |
| [General Rules: genrule](/versions/9.2.0/reference/be/general#genrule). | |
| In other cases, the name is significant: for `*_binary` and `*_test` rules, | |
| for example, the rule name determines the name of the executable produced by | |
| the build. | |
| This directed acyclic graph over targets is called the _target graph_ or | |
| _build dependency graph_, and is the domain over which the | |
| [Bazel Query tool](/versions/9.2.0/query/guide) operates. | |