blob: c7355c61807d30cbf07639fede3fefb127af797e [file] [log] [blame] [view]
Yun Peng1f63afa2016-06-24 18:01:03 +00001---
dzc22b85a22017-05-31 20:37:50 +02002layout: documentation
Googler8af9dc52017-06-07 13:49:48 -04003title: Build Tutorial - Java
Yun Peng1f63afa2016-06-24 18:01:03 +00004---
dzc22b85a22017-05-31 20:37:50 +02005
laurentlb27bb9482018-11-12 12:50:34 -08006# Introduction to Bazel: Building a Java Project
dzc22b85a22017-05-31 20:37:50 +02007
Googler8af9dc52017-06-07 13:49:48 -04008In this tutorial, you'll learn the basics of building Java applications with
9Bazel. You will set up your workspace and build a simple Java project that
10illustrates key Bazel concepts, such as targets and `BUILD` files.
dzc22b85a22017-05-31 20:37:50 +020011
Googler8af9dc52017-06-07 13:49:48 -040012Estimated completion time: 30 minutes.
dzc22b85a22017-05-31 20:37:50 +020013
Googler8af9dc52017-06-07 13:49:48 -040014## What you'll learn
dzc22b85a22017-05-31 20:37:50 +020015
16In this tutorial you'll learn how to:
17
Googler8af9dc52017-06-07 13:49:48 -040018* Build a target
19* Visualize the project's dependencies
20* Split the project into multiple targets and packages
21* Control target visibility across packages
22* Reference targets through labels
23* Deploy a target
dzc22b85a22017-05-31 20:37:50 +020024
Googler1c6a9822017-08-04 19:31:14 +020025## Contents
laurentlb27bb9482018-11-12 12:50:34 -080026{:.no_toc}
Googler1c6a9822017-08-04 19:31:14 +020027
laurentlb27bb9482018-11-12 12:50:34 -080028* ToC
29{:toc}
30
Googler1c6a9822017-08-04 19:31:14 +020031
dzc22b85a22017-05-31 20:37:50 +020032## Before you begin
33
Googler1c6a9822017-08-04 19:31:14 +020034### Install Bazel
35
dzc205125b2017-06-26 11:01:47 +020036To prepare for the tutorial, first [Install Bazel](../install.md) if
Googler1c6a9822017-08-04 19:31:14 +020037you don't have it installed already.
38
Laszlo Csomor75748652018-07-26 07:38:14 -070039### Install the JDK
40
411. Install Java 8 JDK.
42
432. Set the JAVA\_HOME environment variable to point to the JDK.
44 * On Linux/macOS:
45
46 export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
47 * On Windows:
48 1. Open Control Panel.
49 2. Go to "System and Security" > "System" > "Advanced System Settings" > "Advanced" tab > "Environment Variables..." .
50 3. Under the "User variables" list (the one on the top), click "New...".
51 4. In the "Variable name" field, enter `JAVA_HOME`.
52 5. Click "Browse Directory...".
Salty Egg5f17a762018-10-11 07:21:51 -070053 6. Navigate to the JDK directory (for example `C:\Program Files\Java\jdk1.8.0_152`).
Laszlo Csomor75748652018-07-26 07:38:14 -070054 7. Click "OK" on all dialog windows.
55
Googler1c6a9822017-08-04 19:31:14 +020056### Get the sample project
57
58Retrieve the sample project from Bazel's GitHub repository:
dzc22b85a22017-05-31 20:37:50 +020059
dzc51dcd282017-06-14 22:52:27 +020060```sh
Googler8af9dc52017-06-07 13:49:48 -040061git clone https://github.com/bazelbuild/examples/
62```
dzc22b85a22017-05-31 20:37:50 +020063
Googler8af9dc52017-06-07 13:49:48 -040064The sample project for this tutorial is in the `examples/java-tutorial`
65directory and is structured as follows:
dzc22b85a22017-05-31 20:37:50 +020066
Googler8af9dc52017-06-07 13:49:48 -040067```
68java-tutorial
Googler8af9dc52017-06-07 13:49:48 -040069├── BUILD
70├── src
71│ └── main
72│ └── java
73│ └── com
74│ └── example
75│ ├── cmdline
76│ │ ├── BUILD
77│ │ └── Runner.java
78│ ├── Greeting.java
79│ └── ProjectRunner.java
80└── WORKSPACE
81```
dzc22b85a22017-05-31 20:37:50 +020082
83## Build with Bazel
84
85### Set up the workspace
86
Googler8af9dc52017-06-07 13:49:48 -040087Before you can build a project, you need to set up its workspace. A workspace is
88a directory that holds your project's source files and Bazel's build outputs. It
89also contains files that Bazel recognizes as special:
dzc22b85a22017-05-31 20:37:50 +020090
Googler8af9dc52017-06-07 13:49:48 -040091* The `WORKSPACE` file, which identifies the directory and its contents as a
92 Bazel workspace and lives at the root of the project's directory structure,
dzc22b85a22017-05-31 20:37:50 +020093
Googler8af9dc52017-06-07 13:49:48 -040094* One or more `BUILD` files, which tell Bazel how to build different parts of
95 the project. (A directory within the workspace that contains a `BUILD` file
96 is a *package*. You will learn about packages later in this tutorial.)
dzc22b85a22017-05-31 20:37:50 +020097
Googler8af9dc52017-06-07 13:49:48 -040098To designate a directory as a Bazel workspace, create an empty file named
99`WORKSPACE` in that directory.
dzc22b85a22017-05-31 20:37:50 +0200100
Googler8af9dc52017-06-07 13:49:48 -0400101When Bazel builds the project, all inputs and dependencies must be in the same
102workspace. Files residing in different workspaces are independent of one
103another unless linked, which is beyond the scope of this tutorial.
dzc22b85a22017-05-31 20:37:50 +0200104
Googler8af9dc52017-06-07 13:49:48 -0400105### Understand the BUILD file
dzc22b85a22017-05-31 20:37:50 +0200106
Googler8af9dc52017-06-07 13:49:48 -0400107A `BUILD` file contains several different types of instructions for Bazel.
108The most important type is the *build rule*, which tells Bazel how to build the
109desired outputs, such as executable binaries or libraries. Each instance
110of a build rule in the `BUILD` file is called a *target* and points to a
111specific set of source files and dependencies. A target can also point to other
112targets.
dzc22b85a22017-05-31 20:37:50 +0200113
Googler8af9dc52017-06-07 13:49:48 -0400114Take a look at the `java-tutorial/BUILD` file:
dzc22b85a22017-05-31 20:37:50 +0200115
Googler8af9dc52017-06-07 13:49:48 -0400116```
117java_binary(
Googler006659e2017-07-20 19:48:05 +0200118 name = "ProjectRunner",
Googler8af9dc52017-06-07 13:49:48 -0400119 srcs = glob(["src/main/java/com/example/*.java"]),
120)
121```
dzc22b85a22017-05-31 20:37:50 +0200122
Googler8af9dc52017-06-07 13:49:48 -0400123In our example, the `ProjectRunner` target instantiates Bazel's built-in
dzc205125b2017-06-26 11:01:47 +0200124[`java_binary` rule](../be/java.html#java_binary). The rule tells Bazel to
Googler8af9dc52017-06-07 13:49:48 -0400125build a `.jar` file and a wrapper shell script (both named after the target).
dzc22b85a22017-05-31 20:37:50 +0200126
Googler8af9dc52017-06-07 13:49:48 -0400127The attributes in the target explicitly state its dependencies and options.
128While the `name` attribute is mandatory, many are optional. For example, in the
129`ProjectRunner` rule target, `name` is the name of the target, `srcs` specifies
130the source files that Bazel uses to build the target, and `main_class` specifies
131the class that contains the main method. (You may have noticed that our example
dzc205125b2017-06-26 11:01:47 +0200132uses [glob](../be/functions.html#glob) to pass a set of source files to Bazel
Googler8af9dc52017-06-07 13:49:48 -0400133instead of listing them one by one.)
dzc22b85a22017-05-31 20:37:50 +0200134
Googler8af9dc52017-06-07 13:49:48 -0400135### Build the project
dzc22b85a22017-05-31 20:37:50 +0200136
Googler8af9dc52017-06-07 13:49:48 -0400137Let's build your sample project. Change into the `java-tutorial` directory
138and run the following command:
dzc22b85a22017-05-31 20:37:50 +0200139
Googler8af9dc52017-06-07 13:49:48 -0400140```
Googler006659e2017-07-20 19:48:05 +0200141bazel build //:ProjectRunner
Googler8af9dc52017-06-07 13:49:48 -0400142```
143Notice the target label - the `//` part is the location of our `BUILD` file
144relative to the root of the workspace (in this case, the root itself), and
145`ProjectRunner` is what we named that target in the `BUILD` file. (You will
146learn about target labels in more detail at the end of this tutorial.)
dzc22b85a22017-05-31 20:37:50 +0200147
Googler8af9dc52017-06-07 13:49:48 -0400148Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200149
Googler8af9dc52017-06-07 13:49:48 -0400150```bash
Googler006659e2017-07-20 19:48:05 +0200151 INFO: Found 1 target...
152 Target //:ProjectRunner up-to-date:
153 bazel-bin/ProjectRunner.jar
154 bazel-bin/ProjectRunner
155 INFO: Elapsed time: 1.021s, Critical Path: 0.83s
Googler8af9dc52017-06-07 13:49:48 -0400156```
dzc22b85a22017-05-31 20:37:50 +0200157
Googler8af9dc52017-06-07 13:49:48 -0400158Congratulations, you just built your first Bazel target! Bazel places build
159outputs in the `bazel-bin` directory at the root of the workspace. Browse
160through its contents to get an idea for Bazel's output structure.
dzc22b85a22017-05-31 20:37:50 +0200161
Googler8af9dc52017-06-07 13:49:48 -0400162Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200163
dzc51dcd282017-06-14 22:52:27 +0200164```sh
Googler8af9dc52017-06-07 13:49:48 -0400165bazel-bin/ProjectRunner
166```
dzc22b85a22017-05-31 20:37:50 +0200167
168### Review the dependency graph
169
Googler8af9dc52017-06-07 13:49:48 -0400170Bazel requires build dependencies to be explicitly declared in BUILD files.
171Bazel uses those statements to create the project's dependency graph, which
172enables accurate incremental builds.
dzc22b85a22017-05-31 20:37:50 +0200173
Googler8af9dc52017-06-07 13:49:48 -0400174Let's visualize our sample project's dependencies. First, generate a text
175representation of the dependency graph (run the command at the workspace root):
dzc22b85a22017-05-31 20:37:50 +0200176
Googler8af9dc52017-06-07 13:49:48 -0400177```
pcloudy22f16e42018-08-31 08:11:48 -0700178bazel query --nohost_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
Googler8af9dc52017-06-07 13:49:48 -0400179```
dzc22b85a22017-05-31 20:37:50 +0200180
Googler8af9dc52017-06-07 13:49:48 -0400181The above command tells Bazel to look for all dependencies for the target
182`//:ProjectRunner` (excluding host and implicit dependencies) and format the
183output as a graph.
dzc22b85a22017-05-31 20:37:50 +0200184
Googler8af9dc52017-06-07 13:49:48 -0400185Then, paste the text into [GraphViz](http://www.webgraphviz.com/).
dzc22b85a22017-05-31 20:37:50 +0200186
dzc22b85a22017-05-31 20:37:50 +0200187
Googler8af9dc52017-06-07 13:49:48 -0400188As you can see, the project has a single target that build two source files with
189no additional dependencies:
dzc22b85a22017-05-31 20:37:50 +0200190
Googler8af9dc52017-06-07 13:49:48 -0400191![Dependency graph of the target 'ProjectRunner'](/assets/tutorial_java_01.svg)
dzc22b85a22017-05-31 20:37:50 +0200192
Googler8af9dc52017-06-07 13:49:48 -0400193Now that you have set up your workspace, built your project, and examined its
194dependencies, let's add some complexity.
dzc22b85a22017-05-31 20:37:50 +0200195
196## Refine your Bazel build
197
Googler8af9dc52017-06-07 13:49:48 -0400198While a single target is sufficient for small projects, you may want to split
199larger projects into multiple targets and packages to allow for fast incremental
200builds (that is, only rebuild what's changed) and to speed up your builds by
201building multiple parts of a project at once.
dzc22b85a22017-05-31 20:37:50 +0200202
Googler8af9dc52017-06-07 13:49:48 -0400203### Specify multiple build targets
dzc22b85a22017-05-31 20:37:50 +0200204
Googler8af9dc52017-06-07 13:49:48 -0400205Let's split our sample project build into two targets. Replace the contents of
206the `java-tutorial/BUILD` file with the following:
dzc22b85a22017-05-31 20:37:50 +0200207
Googler8af9dc52017-06-07 13:49:48 -0400208```
209java_binary(
210 name = "ProjectRunner",
211 srcs = ["src/main/java/com/example/ProjectRunner.java"],
212 main_class = "com.example.ProjectRunner",
213 deps = [":greeter"],
214)
dzc22b85a22017-05-31 20:37:50 +0200215
Googler8af9dc52017-06-07 13:49:48 -0400216java_library(
217 name = "greeter",
218 srcs = ["src/main/java/com/example/Greeting.java"],
219)
220```
dzc22b85a22017-05-31 20:37:50 +0200221
Googler8af9dc52017-06-07 13:49:48 -0400222With this configuration, Bazel first builds the `greeter` library, then the
Passw473a9162017-12-22 14:13:12 -0800223`ProjectRunner` binary. The `deps` attribute in `java_binary` tells Bazel that
Googler8af9dc52017-06-07 13:49:48 -0400224the `greeter` library is required to build the `ProjectRunner` binary.
dzc22b85a22017-05-31 20:37:50 +0200225
Googler8af9dc52017-06-07 13:49:48 -0400226Let's build this new version of our project. Run the following command:
dzc22b85a22017-05-31 20:37:50 +0200227
Googler8af9dc52017-06-07 13:49:48 -0400228```
229bazel build //:ProjectRunner
230```
dzc22b85a22017-05-31 20:37:50 +0200231
Googler8af9dc52017-06-07 13:49:48 -0400232Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200233
Googler8af9dc52017-06-07 13:49:48 -0400234```
235INFO: Found 1 target...
236Target //:ProjectRunner up-to-date:
237 bazel-bin/ProjectRunner.jar
238 bazel-bin/ProjectRunner
239INFO: Elapsed time: 2.454s, Critical Path: 1.58s
240```
dzc22b85a22017-05-31 20:37:50 +0200241
Googler8af9dc52017-06-07 13:49:48 -0400242Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200243
Googler8af9dc52017-06-07 13:49:48 -0400244```
245bazel-bin/ProjectRunner
246```
dzc22b85a22017-05-31 20:37:50 +0200247
Googler8af9dc52017-06-07 13:49:48 -0400248If you now modify `ProjectRunner.java` and rebuild the project, Bazel only
249recompiles that file.
dzc22b85a22017-05-31 20:37:50 +0200250
Googler8af9dc52017-06-07 13:49:48 -0400251Looking at the dependency graph, you can see that `ProjectRunner` depends on the
252same inputs as it did before, but the structure of the build is different:
dzc22b85a22017-05-31 20:37:50 +0200253
laurentlb79b94312018-11-07 05:18:59 -0800254![Dependency graph of the target 'ProjectRunner' after adding a dependency](
255/assets/tutorial_java_02.svg)
dzc22b85a22017-05-31 20:37:50 +0200256
Googler8af9dc52017-06-07 13:49:48 -0400257You've now built the project with two targets. The `ProjectRunner` target builds
258two source files and depends on one other target (`:greeter`), which builds
259one additional source file.
dzc22b85a22017-05-31 20:37:50 +0200260
261### Use multiple packages
262
Googler8af9dc52017-06-07 13:49:48 -0400263Lets now split the project into multiple packages. If you take a look at the
264`src/main/java/com/example/cmdline` directory, you can see that it also contains
265a `BUILD` file, plus some source files. Therefore, to Bazel, the workspace now
266contains two packages, `//src/main/java/com/example/cmdline` and `//` (since
267there is a `BUILD` file at the root of the workspace).
dzc22b85a22017-05-31 20:37:50 +0200268
Googler8af9dc52017-06-07 13:49:48 -0400269Take a look at the `src/main/java/com/example/cmdline/BUILD` file:
dzc22b85a22017-05-31 20:37:50 +0200270
Googler8af9dc52017-06-07 13:49:48 -0400271```
272java_binary(
273 name = "runner",
274 srcs = ["Runner.java"],
275 main_class = "com.example.cmdline.Runner",
276 deps = ["//:greeter"]
277)
278```
dzc22b85a22017-05-31 20:37:50 +0200279
Googler8af9dc52017-06-07 13:49:48 -0400280The `runner` target depends on the `greeter` target in the `//` package (hence
281the target label `//:greeter`) - Bazel knows this through the `deps` attribute.
282Take a look at the dependency graph:
dzc22b85a22017-05-31 20:37:50 +0200283
Googler8af9dc52017-06-07 13:49:48 -0400284![Dependency graph of the target 'runner'](/assets/tutorial_java_03.svg)
dzc22b85a22017-05-31 20:37:50 +0200285
Peter Laird4b16e022017-10-12 16:44:19 +0200286However, for the build to succeed, you must explicitly give the `runner` target in
287`//src/main/java/com/example/cmdline/BUILD` visibility to targets in
Googler8af9dc52017-06-07 13:49:48 -0400288`//BUILD` using the `visibility` attribute. This is because by default targets
289are only visible to other targets in the same `BUILD` file. (Bazel uses target
290visibility to prevent issues such as libraries containing implementation details
291leaking into public APIs.)
dzc22b85a22017-05-31 20:37:50 +0200292
Googler8af9dc52017-06-07 13:49:48 -0400293To do this, add the `visibility` attribute to the `greeter` target in
294`java-tutorial/BUILD` as shown below:
dzc22b85a22017-05-31 20:37:50 +0200295
Googler8af9dc52017-06-07 13:49:48 -0400296```
297java_library(
298 name = "greeter",
299 srcs = ["src/main/java/com/example/Greeting.java"],
300 visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
dzc22b85a22017-05-31 20:37:50 +0200301 )
Googler8af9dc52017-06-07 13:49:48 -0400302```
dzc22b85a22017-05-31 20:37:50 +0200303
Googler8af9dc52017-06-07 13:49:48 -0400304Let's now build the new package. Run the following command at the root of the
305workspace:
dzc22b85a22017-05-31 20:37:50 +0200306
Googler8af9dc52017-06-07 13:49:48 -0400307```
308bazel build //src/main/java/com/example/cmdline:runner
309```
dzc22b85a22017-05-31 20:37:50 +0200310
Googler8af9dc52017-06-07 13:49:48 -0400311Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200312
Googler8af9dc52017-06-07 13:49:48 -0400313```
314INFO: Found 1 target...
315Target //src/main/java/com/example/cmdline:runner up-to-date:
316 bazel-bin/src/main/java/com/example/cmdline/runner.jar
317 bazel-bin/src/main/java/com/example/cmdline/runner
318 INFO: Elapsed time: 1.576s, Critical Path: 0.81s
319```
dzc22b85a22017-05-31 20:37:50 +0200320
Googler8af9dc52017-06-07 13:49:48 -0400321Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200322
Googler8af9dc52017-06-07 13:49:48 -0400323```
324./bazel-bin/src/main/java/com/example/cmdline/runner
dzc22b85a22017-05-31 20:37:50 +0200325
Googler8af9dc52017-06-07 13:49:48 -0400326```
dzc22b85a22017-05-31 20:37:50 +0200327
Googler8af9dc52017-06-07 13:49:48 -0400328You've now modified the project to build as two packages, each containing one
329target, and understand the dependencies between them.
dzc22b85a22017-05-31 20:37:50 +0200330
dzc22b85a22017-05-31 20:37:50 +0200331
332## Use labels to reference targets
333
Googler8af9dc52017-06-07 13:49:48 -0400334In `BUILD` files and at the command line, Bazel uses target labels to reference
335targets - for example, `//:ProjectRunner` or
336`//src/main/java/com/example/cmdline:runner`. Their syntax is as follows:
dzc22b85a22017-05-31 20:37:50 +0200337
338```
Googler8af9dc52017-06-07 13:49:48 -0400339//path/to/package:target-name
dzc22b85a22017-05-31 20:37:50 +0200340```
341
Googler8af9dc52017-06-07 13:49:48 -0400342If the target is a rule target, then `path/to/package` is the path to the
343directory containing the `BUILD` file, and `target-name` is what you named the
344target in the `BUILD` file (the `name` attribute). If the target is a file
345target, then `path/to/package` is the path to the root of the package, and
346`target-name` is the name of the target file, including its full path.
dzc22b85a22017-05-31 20:37:50 +0200347
Googler8af9dc52017-06-07 13:49:48 -0400348When referencing targets within the same package, you can skip the package path
349and just use `//:target-name`. When referencing targets within the same `BUILD`
350file, you can even skip the `//` workspace root identifier and just use
351`:target-name`.
dzc22b85a22017-05-31 20:37:50 +0200352
Googler8af9dc52017-06-07 13:49:48 -0400353For example, for targets in the `java-tutorial/BUILD` file, you did not have to
354specify a package path, since the workspace root is itself a package (`//`), and
355your two target labels were simply `//:ProjectRunner` and `//:greeter`.
dzc22b85a22017-05-31 20:37:50 +0200356
Googler8af9dc52017-06-07 13:49:48 -0400357However, for targets in the `//src/main/java/com/example/cmdline/BUILD` file you
358had to specify the full package path of `//src/main/java/com/example/cmdline`
359and your target label was `//src/main/java/com/example/cmdline:runner`.
dzc22b85a22017-05-31 20:37:50 +0200360
361## Package a Java target for deployment
362
Googler8af9dc52017-06-07 13:49:48 -0400363Lets now package a Java target for deployment by building the binary with all
364of its runtime dependencies. This lets you run the binary outside of your
365development environment.
dzc22b85a22017-05-31 20:37:50 +0200366
dzc205125b2017-06-26 11:01:47 +0200367As you remember, the [java_binary](../be/java.html#java_binary) build rule
Googler8af9dc52017-06-07 13:49:48 -0400368produces a `.jar` and a wrapper shell script. Take a look at the contents of
369`runner.jar` using this command:
dzc22b85a22017-05-31 20:37:50 +0200370
Googler8af9dc52017-06-07 13:49:48 -0400371```
372jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
373```
dzc22b85a22017-05-31 20:37:50 +0200374
Googler8af9dc52017-06-07 13:49:48 -0400375The contents are:
dzc22b85a22017-05-31 20:37:50 +0200376
Googler8af9dc52017-06-07 13:49:48 -0400377```
378META-INF/
379META-INF/MANIFEST.MF
380com/
381com/example/
382com/example/cmdline/
383com/example/cmdline/Runner.class
384```
385As you can see, `runner.jar` contains `Runner.class`, but not its dependency,
386`Greeting.class`. The `runner` script that Bazel generates adds `greeter.jar`
387to the classpath, so if you leave it like this, it will run locally, but it
388won't run standalone on another machine. Fortunately, the `java_binary` rule
389allows you to build a self-contained, deployable binary. To build it, add the
390`_deploy.jar` suffix to the file name when building `runner.jar`
391(<target-name>_deploy.jar):
dzc22b85a22017-05-31 20:37:50 +0200392
Googler8af9dc52017-06-07 13:49:48 -0400393```
394bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
395```
dzc22b85a22017-05-31 20:37:50 +0200396
Googler8af9dc52017-06-07 13:49:48 -0400397Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200398
Googler8af9dc52017-06-07 13:49:48 -0400399```
400INFO: Found 1 target...
401Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
402 bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
403INFO: Elapsed time: 1.700s, Critical Path: 0.23s
404```
405You have just built `runner_deploy.jar`, which you can run standalone away from
406your development environment since it contains the required runtime
407dependencies.
dzc22b85a22017-05-31 20:37:50 +0200408
Googler8af9dc52017-06-07 13:49:48 -0400409## Further reading
dzc22b85a22017-05-31 20:37:50 +0200410
dzc205125b2017-06-26 11:01:47 +0200411* [External Dependencies](../external.html) to learn more about working with
412 local and remote repositories.
dzc22b85a22017-05-31 20:37:50 +0200413
dzc205125b2017-06-26 11:01:47 +0200414* The [Build Encyclopedia](../be/overview.html) to learn more about Bazel.
dzc22b85a22017-05-31 20:37:50 +0200415
dzc205125b2017-06-26 11:01:47 +0200416* The [C++ build tutorial](../tutorial/cpp.md) to get started with building
Googler8af9dc52017-06-07 13:49:48 -0400417 C++ projects with Bazel.
dzc22b85a22017-05-31 20:37:50 +0200418
Laszlo Csomor5d357942018-06-12 01:56:45 -0700419* The [Android application tutorial](../tutorial/android-app.md) and
420 [iOS application tutorial](../tutorial/ios-app.md) to get started with
Googler8af9dc52017-06-07 13:49:48 -0400421 building mobile applications for Android and iOS with Bazel.
dzc22b85a22017-05-31 20:37:50 +0200422
Googler8af9dc52017-06-07 13:49:48 -0400423Happy building!
dzc22b85a22017-05-31 20:37:50 +0200424