> ## Documentation Index
> Fetch the complete documentation index at: https://preview.bazel.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Bazel Tutorial: Build a C++ Project

<h2 id="introduction">
  Introduction
</h2>

New to Bazel? You're in the right place. Follow this First Build tutorial for a
simplified introduction to using Bazel. This tutorial defines key terms as they
are used in Bazel's context and walks you through the basics of the Bazel
workflow. Starting with the tools you need, you will build and run three
projects with increasing complexity and learn how and why they get more complex.

While Bazel is a [build system](https://bazel.build/basics/build-systems) that
supports multi-language builds, this tutorial uses a C++ project as an example
and provides the general guidelines and flow that apply to most languages.

Estimated completion time: 30 minutes.

<h3 id="prerequisites">
  Prerequisites
</h3>

Start by [installing Bazel](https://bazel.build/install), if you haven't
already. This tutorial uses Git for source control, so for best results [install Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) as well.

Next, retrieve the sample project from Bazel's GitHub repository by running the
following in your command-line tool of choice:

```posix-terminal theme={null}
git clone https://github.com/bazelbuild/examples
```

The sample project for this tutorial is in the `examples/cpp-tutorial`
directory.

Take a look at how it's structured:

```none theme={null}
examples
└── cpp-tutorial
    ├──stage1
    │  ├── main
    │  │   ├── BUILD
    │  │   └── hello-world.cc
    │  └── MODULE.bazel
    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── MODULE.bazel
    └──stage3
       ├── main
       │   ├── BUILD
       │   ├── hello-world.cc
       │   ├── hello-greet.cc
       │   └── hello-greet.h
       ├── lib
       │   ├── BUILD
       │   ├── hello-time.cc
       │   └── hello-time.h
       └── MODULE.bazel
```

There are three sets of files, each set representing a stage in this tutorial.
In the first stage, you will build a single [target](https://bazel.build/reference/glossary#target) residing in a single [package](https://bazel.build/reference/glossary#package). In the second stage, you will
build both a binary and a library from a single package. In the third and final
stage, you will build a project with multiple packages and build it with
multiple targets.

<h3 id="summary-introduction">
  Summary: Introduction
</h3>

By installing Bazel (and Git) and cloning the repository for this tutorial, you
have laid the foundation for your first build with Bazel. Continue to the next
section to define some terms and set up your
[workspace](https://bazel.build/reference/glossary#workspace).

<h2 id="getting-started">
  Getting started
</h2>

Before you can build a project, you need to set up its workspace. A workspace
is a directory that holds your project's source files and Bazel's build outputs.
It also contains these significant files:

* The `MODULE.bazel` file, which identifies the directory and its contents as
  a Bazel workspace and lives at the root of the project's directory
  structure. It's also where you specify your external dependencies.
* One or more [`BUILD` files](https://bazel.build/reference/glossary#build-file), which tell Bazel
  how to build different parts of the project. A directory within the
  workspace that contains a `BUILD` file is a
  [package](https://bazel.build/reference/glossary#package). (More on packages
  later in this tutorial.)

In future projects, to designate a directory as a Bazel workspace, create an
empty file named `MODULE.bazel` in that directory. For the purposes of this
tutorial, a `MODULE.bazel` file is already present in each stage.

<h3 id="understand-build">
  Understand the BUILD file
</h3>

A `BUILD` file contains several different types of instructions for Bazel. Each
`BUILD` file requires at least one
[rule](https://bazel.build/reference/glossary#rule) as a set of instructions,
which tells Bazel how to build the outputs you want, such as executable binaries
or libraries. Each instance of a build rule in the `BUILD` file is called a
[target](https://bazel.build/reference/glossary#target) and points to a specific
set of source files and
[dependencies](https://bazel.build/reference/glossary#dependency). A target can
also point to other targets.

Take a look at the `BUILD` file in the `cpp-tutorial/stage1/main` directory:

```bazel theme={null}
cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)
```

In our example, the `hello-world` target instantiates Bazel's built-in
[`cc_binary` rule](https://bazel.build/reference/be/c-cpp#cc_binary). The rule
tells Bazel to build a self-contained executable binary from the
`hello-world.cc` source file with no dependencies.

<h3 id="summary-getting-started">
  Summary: getting started
</h3>

Now you are familiar with some key terms, and what they mean in the context of
this project and Bazel in general. In the next section, you will build and test
Stage 1 of the project.

<h2 id="stage-1">
  Stage 1: single target, single package
</h2>

It's time to build the first part of the project. For a visual reference, the
structure of the Stage 1 section of the project is:

```none theme={null}
examples
└── cpp-tutorial
    └──stage1
       ├── main
       │   ├── BUILD
       │   └── hello-world.cc
       └── MODULE.bazel
```

Run the following to move to the `cpp-tutorial/stage1` directory:

```posix-terminal theme={null}
cd cpp-tutorial/stage1
```

Next, run:

```posix-terminal theme={null}
bazel build //main:hello-world
```

In the target label, the `//main:` part is the location of the `BUILD` file
relative to the root of the workspace, and `hello-world` is the target name in
the `BUILD` file.

Bazel produces something that looks like this:

```none theme={null}
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
```

You just built your first Bazel target. Bazel places build outputs in the
`bazel-bin` directory at the root of the workspace.

Now test your freshly built binary, which is:

```posix-terminal theme={null}
bazel-bin/main/hello-world
```

This results in a printed "`Hello world`" message.

Here's the dependency graph of Stage 1:

<img src="https://mintcdn.com/bazel/bQLJmftpsaCHxjA2/docs/images/cpp-tutorial-stage1.png?fit=max&auto=format&n=bQLJmftpsaCHxjA2&q=85&s=e42e696e84c120943c453ca06eb7e3e6" alt="Dependency graph for hello-world displays a single target with a single source file." width="193" height="155" data-path="docs/images/cpp-tutorial-stage1.png" />

<h3 id="summary-stage-1">
  Summary: stage 1
</h3>

Now that you have completed your first build, you have a basic idea of how a
build is structured. In the next stage, you will add complexity by adding
another target.

<h2 id="stage-2">
  Stage 2: multiple build targets
</h2>

While a single target is sufficient for small projects, you may want to split
larger projects into multiple targets and packages. This allows for fast
incremental builds – that is, Bazel only rebuilds what's changed – and speeds up
your builds by building multiple parts of a project at once. This stage of the
tutorial adds a target, and the next adds a package.

This is the directory you are working with for Stage 2:

```none theme={null}
    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── MODULE.bazel
```

Take a look at the `BUILD` file in the `cpp-tutorial/stage2/main` directory:

```bazel theme={null}
cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)
```

With this `BUILD` file, Bazel first builds the `hello-greet` library (using
Bazel's built-in [`cc_library` rule](https://bazel.build/reference/be/c-cpp#cc_library)), then the
`hello-world` binary. The `deps` attribute in the `hello-world` target tells
Bazel that the `hello-greet` library is required to build the `hello-world`
binary.

Before you can build this new version of the project, you need to change
directories, switching to the `cpp-tutorial/stage2` directory by running:

```posix-terminal theme={null}
cd ../stage2
```

Now you can build the new binary using the following familiar command:

```posix-terminal theme={null}
bazel build //main:hello-world
```

Once again, Bazel produces something that looks like this:

```none theme={null}
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
```

Now you can test your freshly built binary, which returns another "`Hello
world`":

```posix-terminal theme={null}
bazel-bin/main/hello-world
```

If you now modify `hello-greet.cc` and rebuild the project, Bazel only
recompiles that file.

Looking at the dependency graph, you can see that `hello-world` depends on an
extra input named `hello-greet`:

<img src="https://mintcdn.com/bazel/bQLJmftpsaCHxjA2/docs/images/cpp-tutorial-stage2.png?fit=max&auto=format&n=bQLJmftpsaCHxjA2&q=85&s=3a02dd0761228204a7241e6a49b1804d" alt="Dependency graph for hello-world displays dependency changes after modification to the file." width="383" height="259" data-path="docs/images/cpp-tutorial-stage2.png" />

<h3 id="summary-stage-2">
  Summary: stage 2
</h3>

You've now built the project with two targets. The `hello-world` target builds
one source file and depends on one other target (`//main:hello-greet`), which
builds two additional source files. In the next section, take it a step further
and add another package.

<h2 id="stage-3">
  Stage 3: multiple packages
</h2>

This next stage adds another layer of complication and builds a project with
multiple packages. Take a look at the structure and contents of the
`cpp-tutorial/stage3` directory:

```none theme={null}
└──stage3
   ├── main
   │   ├── BUILD
   │   ├── hello-world.cc
   │   ├── hello-greet.cc
   │   └── hello-greet.h
   ├── lib
   │   ├── BUILD
   │   ├── hello-time.cc
   │   └── hello-time.h
   └── MODULE.bazel
```

You can see that now there are two sub-directories, and each contains a `BUILD`
file. Therefore, to Bazel, the workspace now contains two packages: `lib` and
`main`.

Take a look at the `lib/BUILD` file:

```bazel theme={null}
cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)
```

And at the `main/BUILD` file:

```bazel theme={null}
cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time",
    ],
)
```

The `hello-world` target in the main package depends on the` hello-time` target
in the `lib` package (hence the target label `//lib:hello-time`) - Bazel knows
this through the `deps` attribute. You can see this reflected in the dependency
graph:

<img src="https://mintcdn.com/bazel/bQLJmftpsaCHxjA2/docs/images/cpp-tutorial-stage3.png?fit=max&auto=format&n=bQLJmftpsaCHxjA2&q=85&s=ce15b035cf0007a89134d97e7fa89bce" alt="Dependency graph for hello-world displays how the target in the main package depends on the target in the lib package." width="550" height="259" data-path="docs/images/cpp-tutorial-stage3.png" />

For the build to succeed, you make the `//lib:hello-time` target in `lib/BUILD`
explicitly visible to targets in `main/BUILD` using the visibility attribute.
This is because by default targets are only visible to other targets in the same
`BUILD` file. Bazel uses target visibility to prevent issues such as libraries
containing implementation details leaking into public APIs.

Now build this final version of the project. Switch to the `cpp-tutorial/stage3`
directory by running:

```posix-terminal theme={null}
cd  ../stage3
```

Once again, run the following command:

```posix-terminal theme={null}
bazel build //main:hello-world
```

Bazel produces something that looks like this:

```none theme={null}
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
```

Now test the last binary of this tutorial for a final `Hello world` message:

```posix-terminal theme={null}
bazel-bin/main/hello-world
```

<h3 id="summary-stage-3">
  Summary: stage 3
</h3>

You've now built the project as two packages with three targets and understood
the dependencies between them, which equips you to go forth and build future
projects with Bazel. In the next section, take a look at how to continue your
Bazel journey.

<h2 id="next-steps">
  Next steps
</h2>

You've now completed your first basic build with Bazel, but this is just the
start. Here are some more resources to continue learning with Bazel:

* To keep focusing on C++, read about common [C++ build use cases](https://bazel.build/tutorials/cpp-use-cases).
* To get started with building other applications with Bazel, see the
  tutorials for [Java](https://bazel.build/start/java), [Android application](https://bazel.build/start/android-app), or [iOS application](https://bazel.build/start/ios-app).
* To learn more about working with local and remote repositories, read about
  [external dependencies](https://bazel.build/docs/external).
* To learn more about Bazel's other rules, see this [reference guide](https://bazel.build/rules).

Happy building!
