# Apollo Build and Test Explained

This document focuses on how to build and test Apollo in different ways.

## Pre-requisites

You are supposed to have followed
[Apollo Software Installation Guide](../quickstart/apollo_software_installation_guide.md).
Make sure you are in Apollo development Docker container before you proceed.

## Overview

Apollo uses [Bazel](https://bazel.build) as its underlying build system. Bazel
is an open-source build and test tool with a human-readable, high-level build
language suitable for medium and large projects. Basically, the better you know
about Bazel, the better you know about Apollo Build.

## Building Apollo

### Subcommands in `apollo.sh`

Let's first take a look at the usage of `apollo.sh`.

![apollo.sh help](images/apollo_sh_help.jpg)

From this message, we can see subcommands that starts with "build\_", like
`build_dbg`, `build_cpu`, and `build_opt_gpu`, etc. As you may figure out, they
are all variants for their basic form: `apollo.sh build`.

### Building Apollo using `apollo.sh build`

You can use `./apollo.sh build` to build individual modules, or the whole Apollo
project.

Type the following command to build, say, Cyber RT:

```bash
bash apollo.sh build cyber
```

To build the whole Planning module (all
[targets](https://docs.bazel.build/versions/master/guide.html#target-patterns)
under the `modules/planning` directory):

```bash
bash apollo.sh build planning
```

To build everything,

```bash
bash apollo.sh build
```

![tip_icon](images/tip_icon.png) For simplicty, Apollo 6.0 introduces the notion
of `bash apollo.sh build [module]` to replace the notion of `build_cyber`,
`build_planning`, etc in previous Apollo releases.

### Variants of `apollo.sh build`

There are mainly four variants of `apollo.sh build`, namely, `build_dbg`,
`build_opt`, `build_cpu` and `build_gpu`.

You may ask, what's the differences among them?

Good question. Let me try to make this clear.

#### Debug v.s. Optimized Build: `build_dbg/build_opt`

By default, Apollo uses the
[fastbuild compilation mode](https://docs.bazel.build/versions/master/user-manual.html#flag--compilation_mode)
. So when you type `bash apollo.sh build planning`, you are indicating Bazel to
run:

```bash
bazel build [other options] -c fastbuild //modules/planning/...
```

for you.

When you type `bash apollo.sh build_dbg planning`, you are running

```bash
bazel build [other options] --config=dbg //modules/planning/...
```

Please note that `--config=dbg` implies `-c dbg`, as can be seen from the
following section from `tools/bazelrc`:

```
build:dbg -c dbg
build:opt -c opt
```

Now you can understand the `build_opt` variant. Basically,

```bash
bash apollo.sh build_opt cyber
```

means

```bash
bazel build [other options] -c opt //cyber/...
```

#### CPU v.s. GPU Build: `build_cpu/build_gpu`

By now, you can easily figure out that `build_cpu` and `build_gpu` are just
another form of running

```bash
bazel build --config=cpu
```

and

```bash
bazel build --config=gpu
```

respectively under the hood.

However, things are a bit complicated compared to the `build_dbg/build_gpu`
case.

Here is a snapshot showing the log messages on my screen when running
`apollo.sh build`:

![use_gpu build](images/build_use_gpu.png)

There are three `USE_GPU`: `USE_GPU_HOST`, `USE_GPU_TARGET` and `USE_GPU`.

- `USE_GPU_HOST` is an environment variable determined by
  `docker/scripts/dev_start.sh` to pass to Apollo Docker container, which
  indicates whether the host machine (where Docker is running) is GPU capable.
- `USE_GPU_TARGET` is an environment variable determined by
  `scripts/apollo.bashrc` inside Docker container to indicate whether the
  container is GPU capable.
- `USE_GPU` is a variable indicating whether to perform CPU build or GPU build.

When you type `bash apollo.sh build --config=cpu` or
`apollo.sh build --config=gpu`, the
[build script](../../scripts/apollo_build.sh)
will check the GPU capability of the Docker container and determines whether the
build you specified can succeed.

![tip_icon](images/tip_icon.png) If you didn't specify whether to perform CPU or
GPU build, the build script will determine it automatically according to GPU
capability of your Docker environment.

![tip_icon](images/tip_icon.png) It's OK to run CPU build in a **GPU capable**
Apollo container, whereas running GPU build in a CPU-only container will fail.

![tip_icon](images/tip_icon.png) By design, `--config=cpu` and `--config=gpu`
are mutually exclusive. You should specify at most one of them when running
`apollo.sh build`.

#### Optimized GPU Build with `build_opt_gpu`

`build_opt_gpu` is just the combination of `build_opt` and `build_gpu`.

```
bash apollo.sh build_opt_gpu
```

is equivalent to

```
bazel build --config=opt --config=gpu //...
```

## Running Unit Tests: `apollo.sh test`

Since `bazel test` inherits all options from `bazel build` (Ref:
[Bazel Docs:Test Options](https://docs.bazel.build/versions/master/command-line-reference.html#test-options)),
the discussions above are applicable to `apollo.sh test`.

```bash
# Each of the following pairs are basically equivalent:

# Run unit tests under the `cyber` directory
bash apollo.sh test cyber
bazel test [--config=cpu|--config=gpu] //cyber/...

# Run unit tests for all in CPU mode
bash apollo.sh test --config=cpu
bazel test --config=cpu //...

# Run unit tests for the Planning module in GPU mode
bash apollo.sh test --config=gpu planning
bazel test --config=gpu //modules/planning/...
```

![tip_icon](images/tip_icon.png) Actually, `apollo.sh test` is equivalent to

```bash
bazel test --config=unit_test
```

All the `cpplint` targets was excluded, since there is an independent
`apollo.sh lint` command.

## Running Code Coverage using `apollo.sh coverage`

Since `bazel coverage` inherits all options from `bazel test`(See
[Bazel Docs: Coverage Options](https://docs.bazel.build/versions/master/command-line-reference.html#coverage-options)),
all the discussions about `apollo.sh test` applies to `apollo.sh coverage`.

## Build/Test/Coverage: An Insider's View

Under the hood, `apollo.sh build/test/coverage` makes use of
[scripts/apollo_build.sh](../../scripts/apollo_build.sh),
[scripts/apollo_test.sh](../../scripts/apollo_test.sh),
and
[scripts/apollo_coverage.sh](../../scripts/apollo_coverage.sh)
respectively.

If you are familiar with Bazel, you can build/test any fine-grained target(s).
For example,

```bash
bazel test -c dbg //cyber/common:file_test
bazel build --config=opt //modules/dreamview/backend
bazel test --config=gpu  //modules/localization/...
```