Yun Peng | 1f63afa | 2016-06-24 18:01:03 +0000 | [diff] [blame] | 1 | --- |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 2 | layout: documentation |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 3 | title: Build Tutorial - C++ |
Yun Peng | 1f63afa | 2016-06-24 18:01:03 +0000 | [diff] [blame] | 4 | --- |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 5 | |
ahumesky | 71c1441 | 2017-12-08 11:55:53 -0800 | [diff] [blame] | 6 | Introduction to Bazel: Building a C++ Project |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 7 | ========== |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 8 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 9 | In this tutorial, you'll learn the basics of building C++ applications with |
| 10 | Bazel. You will set up your workspace and build a simple C++ project that |
| 11 | illustrates key Bazel concepts, such as targets and `BUILD` files. After |
| 12 | completing this tutorial, take a look at |
Yves Junqueira | 83d0d90 | 2018-01-03 05:22:53 -0800 | [diff] [blame] | 13 | [Common C++ Build Use Cases](../cpp-use-cases.md) for information on more advanced |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 14 | concepts such as writing and running C++ tests. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 15 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 16 | Estimated completion time: 30 minutes. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 17 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 18 | ## What you'll learn |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 19 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 20 | In this tutorial you'll learn how to: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 21 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 22 | * Build a target |
| 23 | * Visualize the project's dependencies |
| 24 | * Split the project into multiple targets and packages |
| 25 | * Control target visibility across packages |
| 26 | * Reference targets through labels |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 27 | |
Googler | 6c31578 | 2017-08-04 20:03:30 +0200 | [diff] [blame] | 28 | ## Contents |
| 29 | |
| 30 | * [Before you begin](#before-you-begin) |
| 31 | * [Install Bazel](#install-bazel) |
| 32 | * [Get the sample project](#get-the-sample-project) |
| 33 | * [Build with Bazel](#build-with-bazel) |
| 34 | * [Set up the workspace](#set-up-the-workspace) |
| 35 | * [Understand the BUILD file](#understand-the-build-file) |
| 36 | * [Build the project](#build-the-project) |
| 37 | * [Review the dependency graph](#review-the-dependency-graph) |
| 38 | * [Refine your Bazel build](#refine-your-bazel-build) |
| 39 | * [Specify multiple build targets](#specify-multiple-build-targets) |
| 40 | * [Use multiple packages](#use-multiple-packages) |
| 41 | * [Use labels to reference targets](#use-labels-to-reference-targets) |
| 42 | * [Further reading](#further-reading) |
| 43 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 44 | ## Before you begin |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 45 | |
dzc | 205125b | 2017-06-26 11:01:47 +0200 | [diff] [blame] | 46 | To prepare for the tutorial, first [Install Bazel](../install.md) if |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 47 | you don't have it installed already. Then, retrieve the sample project from |
| 48 | Bazel's GitHub repository: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 49 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 50 | ``` |
| 51 | git clone https://github.com/bazelbuild/examples/ |
| 52 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 53 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 54 | The sample project for this tutorial is in the `examples/cpp-tutorial` directory |
| 55 | and is structured as follows: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 56 | |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 57 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 58 | ``` |
| 59 | examples |
| 60 | └── cpp-tutorial |
| 61 | ├──stage1 |
| 62 | │ └── main |
| 63 | │ ├── BUILD |
| 64 | │ ├── hello-world.cc |
| 65 | │ └── WORKSPACE |
| 66 | ├──stage2 |
| 67 | │ ├── main |
| 68 | │ │ ├── BUILD |
| 69 | │ │ ├── hello-world.cc |
| 70 | │ │ ├── hello-greet.cc |
| 71 | │ │ ├── hello-greet.h |
| 72 | │ └── WORKSPACE |
| 73 | └──stage3 |
| 74 | ├── main |
| 75 | │ ├── BUILD |
| 76 | │ ├── hello-world.cc |
| 77 | │ ├── hello-greet.cc |
| 78 | │ └── hello-greet.h |
| 79 | ├── lib |
| 80 | │ ├── BUILD |
| 81 | │ ├── hello-time.cc |
| 82 | │ └── hello-time.h |
| 83 | └── WORKSPACE |
| 84 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 85 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 86 | As you can see, there are three sets of files, each set representing a stage in |
| 87 | this tutorial. In the first stage, you will build a single target residing in a |
| 88 | single package. In the second stage, you will split your project into multiple |
| 89 | targets but keep it in a single package. In the third and final stage, you will |
| 90 | split your project into multiple packages and build it with multiple targets. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 91 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 92 | ## Build with Bazel |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 93 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 94 | ### Set up the workspace |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 95 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 96 | Before you can build a project, you need to set up its workspace. A workspace is |
| 97 | a directory that holds your project's source files and Bazel's build outputs. It |
| 98 | also contains files that Bazel recognizes as special: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 99 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 100 | * The `WORKSPACE` file, which identifies the directory and its contents as a |
| 101 | Bazel workspace and lives at the root of the project's directory structure, |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 102 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 103 | * One or more `BUILD` files, which tell Bazel how to build different parts of |
| 104 | the project. (A directory within the workspace that contains a `BUILD` file |
| 105 | is a *package*. You will learn about packages later in this tutorial.) |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 106 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 107 | To designate a directory as a Bazel workspace, create an empty file named |
| 108 | `WORKSPACE` in that directory. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 109 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 110 | When Bazel builds the project, all inputs and dependencies must be in the same |
| 111 | workspace. Files residing in different workspaces are independent of one |
| 112 | another unless linked, which is beyond the scope of this tutorial. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 113 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 114 | ### Understand the BUILD file |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 115 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 116 | A `BUILD` file contains several different types of instructions for Bazel. |
| 117 | The most important type is the *build rule*, which tells Bazel how to build the |
| 118 | desired outputs, such as executable binaries or libraries. Each instance |
| 119 | of a build rule in the `BUILD` file is called a *target* and points to a |
| 120 | specific set of source files and dependencies. A target can also point to other |
| 121 | targets. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 122 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 123 | Take a look at the `BUILD` file in the `cpp-tutorial/stage1/main` directory: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 124 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 125 | ``` |
| 126 | cc_binary( |
| 127 | name = "hello-world", |
| 128 | srcs = ["hello-world.cc"], |
| 129 | ) |
| 130 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 131 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 132 | In our example, the `hello-world` target instantiates Bazel's built-in |
Yi Cheng | 9e18b0a | 2017-08-09 10:34:27 +0200 | [diff] [blame] | 133 | [`cc_binary` rule](../be/c-cpp.html#cc_binary). The rule tells Bazel to build |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 134 | a self-contained executable binary from the `hello-world.cc` source file with no |
| 135 | dependencies. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 136 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 137 | The attributes in the target explicitly state its dependencies and options. |
| 138 | While the `name` attribute is mandatory, many are optional. For example, in the |
Googler | c89a8ac | 2017-09-19 23:31:41 +0200 | [diff] [blame] | 139 | `hello-world` target, `name` is self-explanatory, and `srcs` specifies the |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 140 | source file(s) from which Bazel builds the target. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 141 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 142 | ### Build the project |
| 143 | |
| 144 | Let's build your sample project. Change into the `cpp-tutorial/stage1` directory |
| 145 | and run the following command: |
| 146 | |
| 147 | ``` |
| 148 | bazel build //main:hello-world |
| 149 | ``` |
| 150 | |
| 151 | Notice the target label - the `//main:` part is the location of our `BUILD` |
| 152 | file relative to the root of the workspace, and `hello-world` is what we named |
| 153 | that target in the `BUILD` file. (You will learn about target labels in more |
| 154 | detail at the end of this tutorial.) |
| 155 | |
| 156 | Bazel produces output similar to the following: |
| 157 | |
| 158 | ``` |
| 159 | INFO: Found 1 target... |
| 160 | Target //main:hello-world up-to-date: |
| 161 | bazel-bin/main/hello-world |
| 162 | INFO: Elapsed time: 2.267s, Critical Path: 0.25s |
| 163 | ``` |
| 164 | |
| 165 | Congratulations, you just built your first Bazel target! Bazel places build |
| 166 | outputs in the `bazel-bin` directory at the root of the workspace. Browse |
| 167 | through its contents to get an idea for Bazel's output structure. |
| 168 | |
| 169 | Now test your freshly built binary: |
| 170 | |
dzc | 51dcd28 | 2017-06-14 22:52:27 +0200 | [diff] [blame] | 171 | ```sh |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 172 | bazel-bin/main/hello-world |
| 173 | ``` |
| 174 | |
| 175 | ### Review the dependency graph |
| 176 | |
| 177 | A successful build has all of its dependencies explicitly stated in the `BUILD` |
| 178 | file. Bazel uses those statements to create the project's dependency graph, |
| 179 | which enables accurate incremental builds. |
| 180 | |
| 181 | Let's visualize our sample project's dependencies. First, generate a text |
| 182 | representation of the dependency graph (run the command at the workspace root): |
| 183 | |
| 184 | ``` |
| 185 | bazel query --nohost_deps --noimplicit_deps 'deps(//main:hello-world)' \ |
| 186 | --output graph |
| 187 | ``` |
| 188 | |
| 189 | The above command tells Bazel to look for all dependencies for the target |
| 190 | `//main:hello-world` (excluding host and implicit dependencies) and format the |
| 191 | output as a graph. |
| 192 | |
| 193 | Then, paste the text into [GraphViz](http://www.webgraphviz.com/). |
| 194 | |
Alex | d21d5d6 | 2017-08-16 13:45:29 +0200 | [diff] [blame] | 195 | As you can see, the first stage of the sample project has a single target |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 196 | that builds a single source file with no additional dependencies: |
| 197 | |
| 198 |  |
| 199 | |
| 200 | Now that you have set up your workspace, built your project, and examined its |
| 201 | dependencies, let's add some complexity. |
| 202 | |
| 203 | ## Refine your Bazel build |
| 204 | |
| 205 | While a single target is sufficient for small projects, you may want to split |
| 206 | larger projects into multiple targets and packages to allow for fast incremental |
| 207 | builds (that is, only rebuild what's changed) and to speed up your builds by |
| 208 | building multiple parts of a project at once. |
| 209 | |
| 210 | ### Specify multiple build targets |
| 211 | |
| 212 | Let's split our sample project build into two targets. Take a look at the |
| 213 | `BUILD` file in the `cpp-tutorial/stage2/main` directory: |
| 214 | |
| 215 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 216 | cc_library( |
| 217 | name = "hello-greet", |
| 218 | srcs = ["hello-greet.cc"], |
| 219 | hdrs = ["hello-greet.h"], |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 220 | ) |
| 221 | |
| 222 | cc_binary( |
| 223 | name = "hello-world", |
| 224 | srcs = ["hello-world.cc"], |
| 225 | deps = [ |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 226 | ":hello-greet", |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 227 | ], |
| 228 | ) |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 229 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 230 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 231 | With this `BUILD` file, Bazel first builds the `hello-greet` library |
Yi Cheng | 9e18b0a | 2017-08-09 10:34:27 +0200 | [diff] [blame] | 232 | (using Bazel's built-in [`cc_library` rule](../be/c-cpp.html#cc_library), |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 233 | then the `hello-world` binary. The `deps` attribute in the `hello-world` target |
| 234 | tells Bazel that the `hello-greet` library is required to build the `hello-world` |
| 235 | binary. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 236 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 237 | Let's build this new version of our project. Change into the |
| 238 | `cpp-tutorial/stage2` directory and run the following command: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 239 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 240 | ``` |
| 241 | bazel build //main:hello-world |
| 242 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 243 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 244 | Bazel produces output similar to the following: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 245 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 246 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 247 | INFO: Found 1 target... |
| 248 | Target //main:hello-world up-to-date: |
| 249 | bazel-bin/main/hello-world |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 250 | INFO: Elapsed time: 2.399s, Critical Path: 0.30s |
| 251 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 252 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 253 | Now test your freshly built binary: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 254 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 255 | ``` |
| 256 | bazel-bin/main/hello-world |
| 257 | ``` |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 258 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 259 | If you now modify `hello-greet.cc` and rebuild the project, Bazel will |
| 260 | only recompile that file. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 261 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 262 | Looking at the dependency graph, you can see that `hello-world` depends on the |
| 263 | same inputs as it did before, but the structure of the build is different: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 264 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 265 |  |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 266 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 267 | You've now built the project with two targets. The `hello-world` target builds |
| 268 | one source file and depends on one other target (`//main:hello-greet`), which |
| 269 | builds two additional source files. |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 270 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 271 | ### Use multiple packages |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 272 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 273 | Let’s now split the project into multiple packages. Take a look at the contents |
| 274 | of the `cpp-tutorial/stage3` directory: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 275 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 276 | ``` |
| 277 | └──stage3 |
| 278 | ├── main |
| 279 | │ ├── BUILD |
| 280 | │ ├── hello-world.cc |
| 281 | │ ├── hello-greet.cc |
| 282 | │ └── hello-greet.h |
| 283 | ├── lib |
| 284 | │ ├── BUILD |
| 285 | │ ├── hello-time.cc |
| 286 | │ └── hello-time.h |
| 287 | └── WORKSPACE |
| 288 | ``` |
| 289 | Notice that we now have two sub-directories, and each contains a `BUILD` file. |
| 290 | Therefore, to Bazel, the workspace now contains two packages, `lib` and `main`. |
| 291 | |
| 292 | Take a look at the `lib/BUILD` file: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 293 | |
| 294 | ```python |
| 295 | cc_library( |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 296 | name = "hello-time", |
| 297 | srcs = ["hello-time.cc"], |
| 298 | hdrs = ["hello-time.h"], |
| 299 | visibility = ["//main:__pkg__"], |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 300 | ) |
| 301 | ``` |
| 302 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 303 | And at the `main/BUILD` file: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 304 | |
| 305 | ```python |
| 306 | cc_library( |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 307 | name = "hello-greet", |
| 308 | srcs = ["hello-greet.cc"], |
| 309 | hdrs = ["hello-greet.h"], |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 310 | ) |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 311 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 312 | cc_binary( |
| 313 | name = "hello-world", |
| 314 | srcs = ["hello-world.cc"], |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 315 | deps = [ |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 316 | ":hello-greet", |
| 317 | "//lib:hello-time", |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 318 | ], |
| 319 | ) |
| 320 | ``` |
| 321 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 322 | As you can see, the `hello-world` target in the `main` package depends on the |
| 323 | `hello-time` target in the `lib` package (hence the target label |
| 324 | `//lib:hello-time`) - Bazel knows this through the `deps` attribute. Take a look |
| 325 | at the dependency graph: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 326 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 327 |  |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 328 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 329 | Notice that for the build to succeed, we make the `//lib:hello-time` target in |
| 330 | `lib/BUILD` explicitly visible to targets in `main/BUILD` using the `visibility` |
| 331 | attribute. This is because by default targets are only visible to other targets |
| 332 | in the same `BUILD` file. (Bazel uses target visibility to prevent issues such |
| 333 | as libraries containing implementation details leaking into public APIs.) |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 334 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 335 | Let's build this final version of our project. Change into the |
| 336 | `cpp-tutorial/stage3` directory and run the following command: |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 337 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 338 | ``` |
| 339 | bazel build //main:hello-world |
dzc | 22b85a2 | 2017-05-31 20:37:50 +0200 | [diff] [blame] | 340 | ``` |
| 341 | |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 342 | Bazel produces output similar to the following: |
| 343 | |
| 344 | ``` |
| 345 | INFO: Found 1 target... |
| 346 | Target //main:hello-world up-to-date: |
| 347 | bazel-bin/main/hello-world |
| 348 | INFO: Elapsed time: 0.167s, Critical Path: 0.00s |
| 349 | ``` |
| 350 | |
| 351 | Now test the freshly built binary: |
| 352 | |
| 353 | ``` |
| 354 | bazel-bin/main/hello-world |
| 355 | ``` |
| 356 | |
| 357 | You've now built the project as two packages with three targets and understand |
| 358 | the dependencies between them. |
| 359 | |
| 360 | ## Use labels to reference targets |
| 361 | |
| 362 | In `BUILD` files and at the command line, Bazel uses *labels* to reference |
| 363 | targets - for example, `//main:hello-world` or `//lib:hello-time`. Their syntax |
| 364 | is: |
| 365 | |
| 366 | ``` |
| 367 | //path/to/package:target-name |
| 368 | ``` |
| 369 | |
| 370 | If the target is a rule target, then `path/to/package` is the path to the |
| 371 | directory containing the `BUILD` file, and `target-name` is what you named the |
| 372 | target in the `BUILD` file (the `name` attribute). If the target is a file |
| 373 | target, then `path/to/package` is the path to the root of the package, and |
| 374 | `target-name` is the name of the target file, including its full path. |
| 375 | |
| 376 | When referencing targets within the same package, you can skip the package path |
| 377 | and just use `//:target-name`. When referencing targets within the same `BUILD` |
| 378 | file, you can even skip the `//` workspace root identifier and just use |
| 379 | `:target-name`. |
| 380 | |
| 381 | |
| 382 | ## Further reading |
| 383 | |
| 384 | Congratulations! You now know the basics of building a C++ project with Bazel. |
Googler | 44f3a3f | 2017-12-11 08:40:40 -0800 | [diff] [blame] | 385 | Next, read up on the most common [C++ build use cases](../cpp-use-cases.md). |
| 386 | Then, check out the following: |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 387 | |
dzc | 205125b | 2017-06-26 11:01:47 +0200 | [diff] [blame] | 388 | * [External Dependencies](../external.html) to learn more about working with |
| 389 | local and remote repositories. |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 390 | |
dzc | 205125b | 2017-06-26 11:01:47 +0200 | [diff] [blame] | 391 | * The [Build Encyclopedia](../be/overview.html) to learn more about Bazel. |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 392 | |
dzc | 205125b | 2017-06-26 11:01:47 +0200 | [diff] [blame] | 393 | * The [Java build tutorial](java.md) to get started with |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 394 | building Java applications with Bazel. |
| 395 | |
dzc | 205125b | 2017-06-26 11:01:47 +0200 | [diff] [blame] | 396 | * The [mobile application tutorial](app.md) to get started with |
Googler | e763441 | 2017-06-07 14:52:50 -0400 | [diff] [blame] | 397 | building mobile applications for Android and iOS with Bazel. |
| 398 | |
| 399 | Happy building! |