All targets belong to exactly one package. The name of a target is called its label. Every label uniquely identifies a target. A typical label in canonical form looks like:
The first part of the label is the repository name,
In the typical case that a label refers to the same repository from which
it is used, the repository identifier may be abbreviated as
@myrepo this label is usually written as
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
this label may be written either of the following ways:
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:
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:
Don't confuse labels like
//my/app with package names. Labels always start
with a repository identifier (often abbreviated
//), but package names never
my/app is the package containing
//my/app/lib (which can also be
A common misconception is that
//my/app refers to a package, or to all the
targets in a package; neither is true. Remember, it is equivalent to
//my/app:app, so it names the
app target in the
my/app package of the
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
my/app/testdata (each of these two directories has its own
BUILD file), the latter package contains a file named
are two ways (one wrong, one correct) to refer to this file within
testdata is a different package, so you can't use a relative path
Correct — refer to
testdata with its full path
Labels starting with
@// are references to the main
repository, which will still work even from external repositories.
@//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
//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.
Lexical specification of a label
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.
The precise details of allowed target names are below.
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
file; the name of a file is its pathname relative to the directory containing
Target names must be composed entirely of characters drawn from the set
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,
forbidden) nor contain multiple consecutive slashes as path separators
foo//bar). Similarly, up-level references (
current-directory references (
./) are forbidden.
Wrong — Do not use `..` to refer to files in other packages
Correct — Use `//package-name:filename`
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
//foo/bar/wiz:wiz, even if there is no such package
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 —
The name of a package is the name of the directory containing its
relative to the top-level directory of the containing repository.
Package names must be composed entirely of characters drawn from the set
@', and '
_', and cannot
start with a slash.
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.
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.
Package names may not contain the substring
//, nor end with a slash.
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.
BUILD files declare targets by invoking rules.
In the example below, we see the declaration of the target
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), that declares a target within the package
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 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.
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.
In other cases, the name is significant: for
for example, the rule name determines the name of the executable produced by
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 operates.