## Bazel projects

A Bazel project is a collection of source and build files that describe:

- How to *build* artifacts, like binaries or data files, and their dependencies.
- How to *run* specific commands, i.e. scripts or executables.
- How to *test* said build artifacts.

A Bazel project is materialized by *a top-level directory* , whose
content follows a *specific layout* and *conventions*.

> [!NOTE]
> **Note:** Bazel does not store build artifacts in the project's directory. For more details, see [this page](https://fuchsia.dev/docs/development/build/bazel_concepts/build_outputs).

## Bazel workspaces

A Bazel workspace is a directory tree that contains a top-level
`WORKSPACE.bazel`^[1](https://fuchsia.dev/fuchsia-src/development/build/bazel_concepts/project_layout#fn1)^ file. This defines the root of a collection of sources
and related build files. A Bazel project can use several workspaces:

- The project's root directory is called the *root* *workspace* , and thus must
  contain a `WORKSPACE.bazel` file.

- A project can also reference *other workspaces* , called *external*
  *repositories*, which correspond to third-party project dependencies.

For example, in:

    /home/user/project/
        WORKSPACE.bazel
        src/
            BUILD.bazel
            extra/
                extra.cc
            lib/
                BUILD.bazel
                foo.cc
                foo.h
            main.cc

The directory `/home/user/project` is a root Bazel workspace, which contains
all the files inside it.

The `WORKSPACE.bazel` file can be empty, but can also contain directives
that reference other workspaces, as explained later.

## Bazel packages

Within a workspace, a directory that contains a `BUILD.bazel`^[2](https://fuchsia.dev/fuchsia-src/development/build/bazel_concepts/project_layout#fn2)^ file defines
a *package*, which is a boundary around a collection of source files and items
that Bazel knows about.

For example, this file layout:

    /home/user/project/
      WORKSPACE.bazel
      BUILD.bazel
      main.cc

Defines a root workspace, located at `/home/user/project` with a single
top-level package, which contains the files `BUILD.bazel` and `main.cc`.

The `BUILD.bazel` file can also contain directives to define named *items*,
such as targets, config conditions and others, that also technically belong
to the package.

Several packages can exist in a single workspace, and *each file can only
belong to one package*. For example, with the following file layout:

    /home/user/project/
      WORKSPACE.bazel
      BUILD.bazel
      main.cc
      lib/
        BUILD.bazel
        foo.cc

The root workspace contains two different packages:

- The top-level package, which still contains the files `BUILD.bazel`
  and `main.cc` (relative to the root workspace directory).

- A second package, which contains the files `lib/BUILD.bazel` and
  `lib/foo.cc`.

Note that the file at `/home/user/project/lib/foo.cc` only belongs
to the second package, not to the first one. This is because
*package* *boundaries* *never* *overlap*.

## `BUILD.bazel` versus `BUILD`

Bazel originates from Google's Blaze, which only works on Linux with
case-sensitive filesystems. Blaze only used the file name `BUILD` to store
build directives.

However, Bazel also needs to run on Windows which has
*case-insensitive* filesystems, and many Google, or non-Google projects
already use a directory named "`build`", which then collides with a file
named "`BUILD`" on such systems.

To solve the issue, Bazel uses `BUILD.bazel` and `WORKSPACE.bazel` as the
default file names, while still supporting `BUILD` and `WORKSPACE` as fallbacks.

> [!NOTE]
> **Note:** For portability, prefer `BUILD.bazel` over `BUILD`, and `WORKSPACE.bazel` over `WORKSPACE` in your own Bazel projects.

## Workspace directives

The root `WORKSPACE.bazel` can be empty, or it can contain directives which
reference other Bazel workspaces, which are called *external repositories*.
These directives always give a name to the repository. For example:

    local_repository(
      name = "my_ssl",
      path = "/home/user/src/openssl-bazel",
    )

Associates the name `my_ssl` with the workspace located at
`/home/user/src/openssl-bazel` on the build machine. This directory must also
contain a `WORKSPACE.bazel` (or `WORKSPACE`) file.

A repository is just an external Bazel workspace with a name. This name is
local to your project, and can later be used to reference items from the
external workspace (see below).

Bazel also supports other directives to download repositories from the
network, or even generate their content programmatically.

## Bazel labels

See [this page](https://fuchsia.dev/docs/development/build/bazel_concepts/labels) for an introduction to Bazel labels.

## Bazel extension (`.bzl`) files

See [this page](https://fuchsia.dev/docs/development/build/bazel_concepts/bzl_files) for an introduction to Bazel extension files.
[](https://issues.fuchsia.dev/issues/new?component=1439230&template=1881640&description=Issue+on:+https://fuchsia.dev/docs/development/build/bazel_concepts/project_layout.md "Report a bug or suggest improvements on this page") [](https://cs.opensource.google/fuchsia/fuchsia/+/main:docs/development/build/bazel_concepts/project_layout.md "View the source code of this page") [](https://ci.android.com/edit?repo=fuchsia/fuchsia/main&file=docs/development/build/bazel_concepts/project_layout.md&cloneRepo=fuchsia/fuchsia:refs/heads/main&fullPath=fuchsia/docs/development/build/bazel_concepts/project_layout.md "Edit the source code of this page")

*** ** * ** ***

1. For legacy reasons, this file can also be simply called `WORKSPACE` [↩](https://fuchsia.dev/fuchsia-src/development/build/bazel_concepts/project_layout#fnref1)

2. Also for legacy reasons, the file can also be simply called `BUILD`. [↩](https://fuchsia.dev/fuchsia-src/development/build/bazel_concepts/project_layout#fnref2)