---
title: 'Workspaces, packages, and targets'
---

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.

## Workspace {:#workspace}

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](/versions/6.1.0/docs/external) 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.

### Repositories {:#repositories}

Code is organized in _repositories_. The directory containing the `WORKSPACE`
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](/versions/6.1.0/reference/be/workspace) section in the
[Build Encyclopedia](/versions/6.1.0/reference/be/overview) and the documentation on
[embedded Starlark repository rules](/versions/6.1.0/rules/lib/repo/index).

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.

## Packages {:#packages}

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`
(or `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/tests`.
Note that `my/app/data` is not a package, but a directory
belonging to package `my/app`.

```
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
```

## Targets {:#targets}

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 the `package` function; they do not generate or consume files.
For more information, refer to the
[`package_group` documentation](/versions/6.1.0/reference/be/functions#package_group).

<a class="button button-with-icon button-primary" href="/versions/6.1.0/concepts/labels">
  Labels<span class="material-icons icon-after" aria-hidden="true">arrow_forward</span>
</a>
