---
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](/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/8.1.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>
<pre class="prettyprint">testdata/testdepot.zip</pre>

<p><span class="compare-better">Correct</span> — refer to <code>testdata</code> with its full path</p>

<pre class="prettyprint">//my/app/testdata:testdepot.zip</pre>


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/8.1.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/8.1.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/8.1.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/8.1.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/8.1.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/8.1.0/query/guide) operates.

<table class="columns">
  <tr>
    <td><a class="button button-with-icon button-primary"
           href="/versions/8.1.0/concepts/build-ref">
        <span class="material-icons" aria-hidden="true">arrow_back</span>Targets</a>
    </td>
    <td><a class="button button-with-icon button-primary"
           href="/versions/8.1.0/concepts/build-files">
        BUILD files<span class="material-icons icon-after" aria-hidden="true">arrow_forward</span></a>
    </td>
  </tr>
</table>
