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
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.
The workspace rules bundled with Bazel are documented in the Workspace Rules section in the Build Encyclopedia and the documentation on embedded Starlark repository rules.
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 added automatically.
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 file named
BUILD.bazel). A 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,
my/app, and the subpackage
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
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
visibility attribute of rules or from the
attribute of the
package function; they do not generate or consume files.
For more information, refer to the