Rewrite of C++ First Build
Draft doc:[]
PiperOrigin-RevId: 461029443
Change-Id: I2bee0abd1fa6ab3d3f6c37dc94941421a11605ce
diff --git a/site/en/tutorials/cpp.md b/site/en/tutorials/cpp.md
index abd3f81..f7405e7 100644
--- a/site/en/tutorials/cpp.md
+++ b/site/en/tutorials/cpp.md
@@ -3,60 +3,59 @@
# Bazel Tutorial: Build a C++ Project
-This tutorial covers the basics of building C++ applications with
-Bazel. You will set up your workspace and build a simple C++ project that
-illustrates key Bazel concepts, such as targets and `BUILD` files. After
-completing this tutorial, take a look at
-[Common C++ Build Use Cases](/tutorials/cpp-use-cases) for information on more advanced
-concepts such as writing and running C++ tests.
+## Introduction
+
+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.
-## What you'll learn
+### Prerequisites
-In this tutorial you learn how to:
+Start by [installing Bazel](https://bazel.build/install), if you haven’t
+already. This tutorial uses Git for file management, so for best results
+[install Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) as
+well.
-* Build a target
-* Visualize the project's dependencies
-* Split the project into multiple targets and packages
-* Control target visibility across packages
-* Reference targets through labels
-
-## Before you begin
-
-To prepare for the tutorial, first [Install Bazel](/install) if
-you don't have it installed already. Then, retrieve the sample project from
-Bazel's GitHub repository:
+Next, retrieve the sample project from Bazel's GitHub repository by running the
+following in your command-line tool of choice:
```
-git clone https://github.com/bazelbuild/examples
+$ git clone https://github.com/bazelbuild/examples
```
-The sample project for this tutorial is in the `examples/cpp-tutorial` directory
-and is structured as follows:
+The sample project for this tutorial is in the `examples/cpp-tutorial` directory.
+Take a look below at how it’s structured:
```
examples
└── cpp-tutorial
├──stage1
│ ├── main
- │ │ ├── BUILD
- │ │ └── hello-world.cc
+ │ │ ├── BUILD
+ │ │ └── hello-world.cc
│ └── WORKSPACE
├──stage2
│ ├── main
- │ │ ├── BUILD
- │ │ ├── hello-world.cc
- │ │ ├── hello-greet.cc
- │ │ └── hello-greet.h
+ │ │ ├── BUILD
+ │ │ ├── hello-world.cc
+ │ │ ├── hello-greet.cc
+ │ │ └── hello-greet.h
│ └── WORKSPACE
└──stage3
├── main
- │ ├── BUILD
- │ ├── hello-world.cc
- │ ├── hello-greet.cc
- │ └── hello-greet.h
+ │ ├── BUILD
+ │ ├── hello-world.cc
+ │ ├── hello-greet.cc
+ │ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
@@ -64,77 +63,116 @@
└── WORKSPACE
```
-As you can see, there are three sets of files, each set representing a stage in
-this tutorial. In the first stage, you will build a single target residing in a
-single package. In the second stage, you will split your project into multiple
-targets but keep it in a single package. In the third and final stage, you will
-split your project into multiple packages and build it with multiple targets.
+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
+use a split project with multiple targets but keep it in a single package. In
+the third and final stage, you will build a project with multiple packages and
+build it with multiple targets.
-## Build with Bazel
+### Summary: Introduction
+
+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.
+
+## Getting started
### Set up the workspace
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 files that Bazel recognizes as special:
+also contains these significant files:
-* The `WORKSPACE` file, which identifies the directory and its contents as a
- Bazel workspace and lives at the root of the project's directory structure,
+* The <code>[WORKSPACE file](https://bazel.build/reference/glossary#workspace-file)
+</code>, which identifies the directory and its contents as a Bazel workspace and
+lives at the root of the project's directory structure
+* One or more <code>[BUILD files](https://bazel.build/reference/glossary#build-file)
+</code>, which tell Bazel how to build different parts of the project. A
+directory within the workspace that contains a <code>BUILD</code> file is a
+[package](https://bazel.build/reference/glossary#package). (More on packages
+later in this tutorial.)
-* One or more `BUILD` files, which tell Bazel how to build different parts of
- the project. (A directory within the workspace that contains a `BUILD` file
- is a *package*. You will learn about packages later in this tutorial.)
+In future projects, to designate a directory as a Bazel workspace, create an
+empty file named WORKSPACE in that directory. For the purposes of this tutorial,
+WORKSPACE files are already present.
-To designate a directory as a Bazel workspace, create an empty file named
-`WORKSPACE` in that directory.
+**NOTE**: When Bazel builds the project, all inputs and dependencies must be in
+the same workspace. Files residing in different workspaces are independent of
+one another unless linked. More detailed information about workspace rules can
+be found in [this guide](https://bazel.build/reference/be/workspace).
-When Bazel builds the project, all inputs and dependencies must be in the same
-workspace. Files residing in different workspaces are independent of one
-another unless linked, which is beyond the scope of this tutorial.
### Understand the BUILD file
-A `BUILD` file contains several different types of instructions for Bazel.
-The most important type is the *build rule*, which tells Bazel how to build the
-desired outputs, such as executable binaries or libraries. Each instance
-of a build rule in the `BUILD` file is called a *target* and points to a
-specific set of source files and dependencies. A target can also point to other
-targets.
+
+A `BUILD` file contains several different types of instructions for Bazel. Each
+BUILD file requires at least one build [rule](https://bazel.build/reference/glossary#rule)
+as a set of instructions, which tells Bazel how to build the desired outputs,
+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:
-```python
+```
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
```
-In our example, the `hello-world` target instantiates Bazel's built-in
-[`cc_binary` rule](/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.
+In our example, the `hello-world` target instantiates Bazel's built-in
+<code>[cc_binary rule](https://bazel.build/reference/be/c-cpp#cc_binary)</code>.
+The rule tells Bazel to build a self-contained executable binary from the
+<code>hello-world.cc</code> source file with no dependencies.
-The attributes in the target explicitly state its dependencies and options.
-While the `name` attribute is mandatory, many are optional. For example, in the
-`hello-world` target, `name` is required and self-explanatory, and `srcs` is
+The attributes in the target explicitly state its dependencies and options. While
+the `name` attribute is mandatory, other attributes are optional. For example, in
+the `hello-world` target, `name` is required and self-explanatory, and `srcs` is
optional and specifies the source file(s) from which Bazel builds the target.
-### Build the project
+### Summary: getting started
-To build your sample project, navigate to the `cpp-tutorial/stage1` directory
-and run:
+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.
+
+
+## Stage 1: single target, single package
+
+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:
```
-bazel build //main:hello-world
+examples
+└── cpp-tutorial
+ └──stage1
+ ├── main
+ │ ├── BUILD
+ │ └── hello-world.cc
+ └── WORKSPACE
```
-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. (You will learn about target labels in more
-detail at the end of this tutorial.)
+Run the following to select the `cpp-tutorial/stage1` directory:
-Bazel produces output similar to the following:
+```
+$ cd ../cpp-tutorial/stage1
+```
+
+Next, run:
+
+```
+$ 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:
```
INFO: Found 1 target...
@@ -143,76 +181,54 @@
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
```
-Congratulations, you just built your first Bazel target! Bazel places build
-outputs in the `bazel-bin` directory at the root of the workspace. Browse
-through its contents to get an idea for Bazel's output structure.
+You just built your first Bazel target. Bazel places build outputs in the
+`bazel-bin` directory at the root of the
+[workspace](https://bazel.build/reference/glossary#workspace).
-Now test your freshly built binary:
-
-```sh
-bazel-bin/main/hello-world
-```
-
-### Review the dependency graph
-
-A successful build has all of its dependencies explicitly stated in the `BUILD`
-file. Bazel uses those statements to create the project's dependency graph,
-which enables accurate incremental builds.
-
-To visualize the sample project's dependencies, you can generate a text
-representation of the dependency graph by running this command at the
-workspace root:
+Now test your freshly built binary, which is:
```
-bazel query --notool_deps --noimplicit_deps "deps(//main:hello-world)" \
- --output graph
+$ bazel-bin/main/hello-world
```
-The above command tells Bazel to look for all dependencies for the target
-`//main:hello-world` (excluding host and implicit dependencies) and format the
-output as a graph.
+This results in a printed “`Hello world`” message.
-Then, paste the text into [GraphViz](http://www.webgraphviz.com/).
+Here’s the dependency graph of Stage 1:
-On Ubuntu, you can view the graph locally by installing GraphViz and the xdot
-Dot Viewer:
+![Dependency graph for hello-world displays a single target with a single source file.]
+(/docs/images/cpp-tutorial-stage1.png "Dependency graph for hello-world displays
+a single target with a single source file.")
-```
-sudo apt update && sudo apt install graphviz xdot
-```
-Then you can generate and view the graph by piping the text output above
-straight to xdot:
+### Summary: stage 1
-```
-xdot <(bazel query --notool_deps --noimplicit_deps "deps(//main:hello-world)" \
- --output graph)
-```
+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.
-As you can see, the first stage of the sample project has a single target
-that builds a single source file with no additional dependencies:
-
-
-
-**Figure 1.** Dependency graph for `hello-world` displays a single target with a single
-source file.
-
-After you set up your workspace, build your project, and examine its
-dependencies, then you can add some complexity.
-
-## Refine your Bazel build
+## Stage 2: multiple build targets
While a single target is sufficient for small projects, you may want to split
-larger projects into multiple targets and packages to allow for fast incremental
-builds (that is, only rebuild what's changed) and to speed up your builds by
-building multiple parts of a project at once.
+larger projects into multiple targets and packages. This allows for fast
+incremental builds – that is, 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.
-### Specify multiple build targets
+This is the directory you will work with for Stage 2:
-You can split the sample project build into two targets. Take a look at the
-`BUILD` file in the `cpp-tutorial/stage2/main` directory:
+```
+ ├──stage2
+ │ ├── main
+ │ │ ├── BUILD
+ │ │ ├── hello-world.cc
+ │ │ ├── hello-greet.cc
+ │ │ └── hello-greet.h
+ │ └── WORKSPACE
+```
-```python
+Take a look below at the `BUILD` file in the `cpp-tutorial/stage2/main` directory:
+
+```
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
@@ -229,19 +245,25 @@
```
With this `BUILD` file, Bazel first builds the `hello-greet` library
-(using Bazel's built-in [`cc_library` rule](/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.
+(using Bazel's built-in <code>[cc_library rule](https://bazel.build/reference/be/c-cpp#cc_library)</code>),
+then the <code>hello-world</code> binary. The <code>deps</code> attribute in
+the <code>hello-world</code> target tells Bazel that the <code>hello-greet</code>
+library is required to build the <code>hello-world</code> binary.
-Next, build this new version of the project. Change into the
-`cpp-tutorial/stage2` directory and run the following command:
+Before you can build this new version of the project, you need to change
+directories, switching to the `cpp-tutorial/stage2` directory by running:
```
-bazel build //main:hello-world
+$ cd ../cpp-tutorial/stage2
```
-Bazel produces output similar to the following:
+Now you can build the new binary using the following familiar command:
+
+```
+$ bazel build //main:hello-world
+```
+
+Once again, Bazel produces something that looks like this:
```
INFO: Found 1 target...
@@ -250,52 +272,54 @@
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
```
-Now test your freshly built binary:
+Now you can test your freshly built binary, which returns another “`Hello world`”:
```
-bazel-bin/main/hello-world
+$ bazel-bin/main/hello-world
```
-If you now modify `hello-greet.cc` and rebuild the project, Bazel will
-only recompile that file.
+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 the
+Looking at the dependency graph, you can see that hello-world depends on the
same inputs as it did before, but the structure of the build is different:
-
+
-**Figure 2.** Dependency graph for `hello-world` displays structure changes after
-modification to the file.
+### Summary: stage 2
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.
+builds two additional source files. In the next section, take it a step further
+and add another package.
-### Use multiple packages
+## Stage 3: multiple packages
-You can split the project into multiple packages. Take a look at the contents
-of the `cpp-tutorial/stage3` directory:
+This next stage adds another layer of complication and builds a project with
+multiple packages. Take a look below at the structure and contents of the
+`cpp-tutorial/stage3` directory:
```
└──stage3
├── main
- │ ├── BUILD
- │ ├── hello-world.cc
- │ ├── hello-greet.cc
- │ └── hello-greet.h
+ │ ├── BUILD
+ │ ├── hello-world.cc
+ │ ├── hello-greet.cc
+ │ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
```
-Notice 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`.
+
+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:
-```python
+```
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
@@ -306,7 +330,7 @@
And at the `main/BUILD` file:
-```python
+```
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
@@ -323,30 +347,33 @@
)
```
-As you can see, 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. Take a look
-at the dependency graph:
+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:
-
+
-**Figure 3.** Dependency graph for `hello-world`displays how the target in the
-main package depends on the target in the lib package.
+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.)
-Notice that 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.)
-
-Next you can build this final version of the project. Change into the
-`cpp-tutorial/stage3` directory and run the following command:
+Now build this final version of the project. Switch to the `cpp-tutorial/stage3`
+directory by running:
```
-bazel build //main:hello-world
+$ cd ../cpp-tutorial/stage3
```
-Bazel produces output similar to the following:
+Once again, run the following command:
+
+```
+$ bazel build //main:hello-world
+```
+
+Bazel produces something that looks like this:
```
INFO: Found 1 target...
@@ -355,59 +382,30 @@
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
```
-Now test the freshly built binary:
+Now test the final binary of this tutorial for a final `Hello world` message:
```
-bazel-bin/main/hello-world
+$ bazel-bin/main/hello-world
```
+### Summary: stage 3
+
You've now built the project as two packages with three targets and understand
-the dependencies between them.
+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.
-## Use labels to reference targets
+## Next steps
-In `BUILD` files and at the command line, Bazel uses *labels* to reference
-targets - for example, `//main:hello-world` or `//lib:hello-time`. Their syntax
-is:
+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:
-```
-//path/to/package:target-name
-```
-
-If the target is a rule target, then `path/to/package` is the path from the
-workspace root (the directory containing the `WORKSPACE` file) to the directory
-containing the `BUILD` file, and `target-name` is what you named the target
-in the `BUILD` file (the `name` attribute). If the target is a file target,
-then `path/to/package` is the path to the root of the package, and
-`target-name` is the name of the target file, including its full
-path relative to the root of the package (the directory containing the
-package's `BUILD` file).
-
-When referencing targets at the repository root, the package path is empty,
-just use `//:target-name`. When referencing targets within the same `BUILD`
-file, you can even skip the `//` workspace root identifier and just use
-`:target-name`.
-
-
-## Further reading
-
-Congratulations! You now know the basics of building a C++ project with Bazel.
-Next, read up on the most common [C++ build use cases](/tutorials/cpp-use-cases).
-
-For more details, see:
-
-* [External Dependencies](/docs/external) to learn more about working with
- local and remote repositories.
-
-* The [other rules](/rules) to learn more about Bazel.
-
-* The [Java build tutorial](/tutorials/java) to get started with
- building Java applications with Bazel.
-
-* The [Android application tutorial](/tutorials/android-app) to get started with
- building mobile applications for Android with Bazel.
-
-* The [iOS application tutorial](/tutorials/ios-app) to get started with
- building mobile applications for iOS 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/tutorials/java), [Android application](https://bazel.build/tutorials/android-app),
+or [iOS application](https://bazel.build/tutorials/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!
diff --git a/site/en/tutorials/cpp_dependency.md b/site/en/tutorials/cpp_dependency.md
new file mode 100644
index 0000000..0f56fd7
--- /dev/null
+++ b/site/en/tutorials/cpp_dependency.md
@@ -0,0 +1,49 @@
+Project: /_project.yaml
+Book: /_book.yaml
+
+# Review the dependency graph
+
+A successful build has all of its dependencies explicitly stated in the `BUILD`
+file. Bazel uses those statements to create the project's dependency graph,
+which enables accurate incremental builds.
+
+To visualize the sample project's dependencies, you can generate a text
+representation of the dependency graph by running this command at the
+workspace root:
+
+```
+bazel query --notool_deps --noimplicit_deps "deps(//main:hello-world)" \
+ --output graph
+```
+
+The above command tells Bazel to look for all dependencies for the target
+`//main:hello-world` (excluding host and implicit dependencies) and format the
+output as a graph.
+
+Then, paste the text into [GraphViz](http://www.webgraphviz.com/).
+
+On Ubuntu, you can view the graph locally by installing GraphViz and the xdot
+Dot Viewer:
+
+```
+sudo apt update && sudo apt install graphviz xdot
+```
+
+Then you can generate and view the graph by piping the text output above
+straight to xdot:
+
+```
+xdot <(bazel query --notool_deps --noimplicit_deps "deps(//main:hello-world)" \
+ --output graph)
+```
+
+As you can see, the first stage of the sample project has a single target
+that builds a single source file with no additional dependencies:
+
+
+
+**Figure 1.** Dependency graph for `hello-world` displays a single target with a single
+source file.
+
+After you set up your workspace, build your project, and examine its
+dependencies, then you can add some complexity.
diff --git a/site/en/tutorials/cpp_labels.md b/site/en/tutorials/cpp_labels.md
new file mode 100644
index 0000000..612538d
--- /dev/null
+++ b/site/en/tutorials/cpp_labels.md
@@ -0,0 +1,26 @@
+Project: /_project.yaml
+Book: /_book.yaml
+
+# Use labels to reference targets
+
+In `BUILD` files and at the command line, Bazel uses *labels* to reference
+targets - for example, `//main:hello-world` or `//lib:hello-time`. Their syntax
+is:
+
+```
+//path/to/package:target-name
+```
+
+If the target is a rule target, then `path/to/package` is the path from the
+workspace root (the directory containing the `WORKSPACE` file) to the directory
+containing the `BUILD` file, and `target-name` is what you named the target
+in the `BUILD` file (the `name` attribute). If the target is a file target,
+then `path/to/package` is the path to the root of the package, and
+`target-name` is the name of the target file, including its full
+path relative to the root of the package (the directory containing the
+package's `BUILD` file).
+
+When referencing targets at the repository root, the package path is empty,
+just use `//:target-name`. When referencing targets within the same `BUILD`
+file, you can even skip the `//` workspace root identifier and just use
+`:target-name`.