Bazel builds software from source code organized in a directory tree called a
workspace. Source files in the workspace are organized in a nested hierarchy of
packages, where each package is a directory that contains a set of related
source files and one
BUILD file. The
BUILD file specifies what software
outputs can be built from the source.
A workspace is a directory tree on your filesystem that contains the source
files for the software you want to build. Each workspace has a text file named
WORKSPACE which may be empty, or may contain references to external
dependencies required to build the outputs.
Directories containing a file called
WORKSPACE are considered the root of a
workspace. Therefore, Bazel ignores any directory trees in a workspace rooted at
a subdirectory containing a
WORKSPACE file, as they form another workspace.
Bazel also supports
WORKSPACE.bazel file as an alias of
WORKSPACE file. If
both files exist,
WORKSPACE.bazel is used.
Code is organized in repositories. The directory containing the
file is the root of the main repository, also called
@. Other, (external)
repositories are defined in the
WORKSPACE file using workspace rules, or
generated from modules and extensions in the Bzlmod system. See external
dependencies overview for more information.
As external repositories are repositories themselves, they often contain a
WORKSPACE file as well. However, these additional
WORKSPACE files are
ignored by Bazel. In particular, repositories depended upon transitively are not
The primary unit of code organization in a repository is the package. A package is a collection of related files and a specification of how they can be used to produce output artifacts.
A package is defined as a directory containing a
BUILD file named either
package includes all files in its directory, plus all subdirectories beneath it,
except those which themselves contain a
BUILD file. From this definition, no
file or directory may be a part of two different packages.
For example, in the following directory tree there are two packages,
and the subpackage
my/app/tests. Note that
my/app/data is not a package, but
a directory belonging to package
src/my/app/BUILD src/my/app/app.cc src/my/app/data/input.txt src/my/app/tests/BUILD src/my/app/tests/test.cc
A package is a container of targets, which are defined in the package's
BUILD file. Most targets are one of two principal kinds, files and rules.
Files are further divided into two kinds. Source files are usually written by the efforts of people, and checked in to the repository. Generated files, sometimes called derived files or output files, are not checked in, but are generated from source files.
The second kind of target is declared with a rule. Each rule instance specifies the relationship between a set of input and a set of output files. The inputs to a rule may be source files, but they also may be the outputs of other rules.
Whether the input to a rule is a source file or a generated file is in most cases immaterial; what matters is only the contents of that file. This fact makes it easy to replace a complex source file with a generated file produced by a rule, such as happens when the burden of manually maintaining a highly structured file becomes too tiresome, and someone writes a program to derive it. No change is required to the consumers of that file. Conversely, a generated file may easily be replaced by a source file with only local changes.
The inputs to a rule may also include other rules. The precise meaning of such relationships is often quite complex and language- or rule-dependent, but intuitively it is simple: a C++ library rule A might have another C++ library rule B for an input. The effect of this dependency is that B's header files are available to A during compilation, B's symbols are available to A during linking, and B's runtime data is available to A during execution.
An invariant of all rules is that the files generated by a rule always belong to the same package as the rule itself; it is not possible to generate files into another package. It is not uncommon for a rule's inputs to come from another package, though.
Package groups are sets of packages whose purpose is to limit accessibility of
certain rules. Package groups are defined by the
package_group function. They
have three properties: the list of packages they contain, their name, and other
package groups they include. The only allowed ways to refer to them are from the
visibility attribute of rules or from the
default_visibility attribute of
package function; they do not generate or consume files. For more
information, refer to the