blob: 5b35c5d9f0e07c75f45bf452c21e04bbb832ca1d [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
ahumesky71c14412017-12-08 11:55:53 -08006Introduction to Bazel: Building a Java Project
dzc22b85a22017-05-31 20:37:50 +02007==========
8
Googler8af9dc52017-06-07 13:49:48 -04009In this tutorial, you'll learn the basics of building Java applications with
10Bazel. You will set up your workspace and build a simple Java project that
11illustrates key Bazel concepts, such as targets and `BUILD` files.
dzc22b85a22017-05-31 20:37:50 +020012
Googler8af9dc52017-06-07 13:49:48 -040013Estimated completion time: 30 minutes.
dzc22b85a22017-05-31 20:37:50 +020014
Googler8af9dc52017-06-07 13:49:48 -040015## What you'll learn
dzc22b85a22017-05-31 20:37:50 +020016
17In this tutorial you'll learn how to:
18
Googler8af9dc52017-06-07 13:49:48 -040019* Build a target
20* Visualize the project's dependencies
21* Split the project into multiple targets and packages
22* Control target visibility across packages
23* Reference targets through labels
24* Deploy a target
dzc22b85a22017-05-31 20:37:50 +020025
Googler1c6a9822017-08-04 19:31:14 +020026## Contents
27
28* [Before you begin](#before-you-begin)
29 * [Install Bazel](#install-bazel)
Laszlo Csomor75748652018-07-26 07:38:14 -070030 * [Install the JDK](#install-the-jdk)
Googler1c6a9822017-08-04 19:31:14 +020031 * [Get the sample project](#get-the-sample-project)
32* [Build with Bazel](#build-with-bazel)
33 * [Set up the workspace](#set-up-the-workspace)
34 * [Understand the BUILD file](#understand-the-build-file)
35 * [Build the project](#build-the-project)
36 * [Review the dependency graph](#review-the-dependency-graph)
37* [Refine your Bazel build](#refine-your-bazel-build)
38 * [Specify multiple build targets](#specify-multiple-build-targets)
39 * [Use multiple packages](#use-multiple-packages)
40* [Use labels to reference targets](#use-labels-to-reference-targets)
41* [Package a Java target for deployment](#package-a-java-target-for-deployment)
42* [Further reading](#further-reading)
43
dzc22b85a22017-05-31 20:37:50 +020044## Before you begin
45
Googler1c6a9822017-08-04 19:31:14 +020046### Install Bazel
47
dzc205125b2017-06-26 11:01:47 +020048To prepare for the tutorial, first [Install Bazel](../install.md) if
Googler1c6a9822017-08-04 19:31:14 +020049you don't have it installed already.
50
Laszlo Csomor75748652018-07-26 07:38:14 -070051### Install the JDK
52
531. Install Java 8 JDK.
54
552. Set the JAVA\_HOME environment variable to point to the JDK.
56 * On Linux/macOS:
57
58 export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
59 * On Windows:
60 1. Open Control Panel.
61 2. Go to "System and Security" > "System" > "Advanced System Settings" > "Advanced" tab > "Environment Variables..." .
62 3. Under the "User variables" list (the one on the top), click "New...".
63 4. In the "Variable name" field, enter `JAVA_HOME`.
64 5. Click "Browse Directory...".
65 6. Navigate to the JDK directory (for example `C:\Program Files\Java\jdk1.8.0_152`).
66 7. Click "OK" on all dialog windows.
67
Googler1c6a9822017-08-04 19:31:14 +020068### Get the sample project
69
70Retrieve the sample project from Bazel's GitHub repository:
dzc22b85a22017-05-31 20:37:50 +020071
dzc51dcd282017-06-14 22:52:27 +020072```sh
Googler8af9dc52017-06-07 13:49:48 -040073git clone https://github.com/bazelbuild/examples/
74```
dzc22b85a22017-05-31 20:37:50 +020075
Googler8af9dc52017-06-07 13:49:48 -040076The sample project for this tutorial is in the `examples/java-tutorial`
77directory and is structured as follows:
dzc22b85a22017-05-31 20:37:50 +020078
Googler8af9dc52017-06-07 13:49:48 -040079```
80java-tutorial
Googler8af9dc52017-06-07 13:49:48 -040081├── BUILD
82├── src
83│ └── main
84│ └── java
85│ └── com
86│ └── example
87│ ├── cmdline
88│ │ ├── BUILD
89│ │ └── Runner.java
90│ ├── Greeting.java
91│ └── ProjectRunner.java
92└── WORKSPACE
93```
dzc22b85a22017-05-31 20:37:50 +020094
95## Build with Bazel
96
97### Set up the workspace
98
Googler8af9dc52017-06-07 13:49:48 -040099Before you can build a project, you need to set up its workspace. A workspace is
100a directory that holds your project's source files and Bazel's build outputs. It
101also contains files that Bazel recognizes as special:
dzc22b85a22017-05-31 20:37:50 +0200102
Googler8af9dc52017-06-07 13:49:48 -0400103* The `WORKSPACE` file, which identifies the directory and its contents as a
104 Bazel workspace and lives at the root of the project's directory structure,
dzc22b85a22017-05-31 20:37:50 +0200105
Googler8af9dc52017-06-07 13:49:48 -0400106* One or more `BUILD` files, which tell Bazel how to build different parts of
107 the project. (A directory within the workspace that contains a `BUILD` file
108 is a *package*. You will learn about packages later in this tutorial.)
dzc22b85a22017-05-31 20:37:50 +0200109
Googler8af9dc52017-06-07 13:49:48 -0400110To designate a directory as a Bazel workspace, create an empty file named
111`WORKSPACE` in that directory.
dzc22b85a22017-05-31 20:37:50 +0200112
Googler8af9dc52017-06-07 13:49:48 -0400113When Bazel builds the project, all inputs and dependencies must be in the same
114workspace. Files residing in different workspaces are independent of one
115another unless linked, which is beyond the scope of this tutorial.
dzc22b85a22017-05-31 20:37:50 +0200116
Googler8af9dc52017-06-07 13:49:48 -0400117### Understand the BUILD file
dzc22b85a22017-05-31 20:37:50 +0200118
Googler8af9dc52017-06-07 13:49:48 -0400119A `BUILD` file contains several different types of instructions for Bazel.
120The most important type is the *build rule*, which tells Bazel how to build the
121desired outputs, such as executable binaries or libraries. Each instance
122of a build rule in the `BUILD` file is called a *target* and points to a
123specific set of source files and dependencies. A target can also point to other
124targets.
dzc22b85a22017-05-31 20:37:50 +0200125
Googler8af9dc52017-06-07 13:49:48 -0400126Take a look at the `java-tutorial/BUILD` file:
dzc22b85a22017-05-31 20:37:50 +0200127
Googler8af9dc52017-06-07 13:49:48 -0400128```
129java_binary(
Googler006659e2017-07-20 19:48:05 +0200130 name = "ProjectRunner",
Googler8af9dc52017-06-07 13:49:48 -0400131 srcs = glob(["src/main/java/com/example/*.java"]),
132)
133```
dzc22b85a22017-05-31 20:37:50 +0200134
Googler8af9dc52017-06-07 13:49:48 -0400135In our example, the `ProjectRunner` target instantiates Bazel's built-in
dzc205125b2017-06-26 11:01:47 +0200136[`java_binary` rule](../be/java.html#java_binary). The rule tells Bazel to
Googler8af9dc52017-06-07 13:49:48 -0400137build a `.jar` file and a wrapper shell script (both named after the target).
dzc22b85a22017-05-31 20:37:50 +0200138
Googler8af9dc52017-06-07 13:49:48 -0400139The attributes in the target explicitly state its dependencies and options.
140While the `name` attribute is mandatory, many are optional. For example, in the
141`ProjectRunner` rule target, `name` is the name of the target, `srcs` specifies
142the source files that Bazel uses to build the target, and `main_class` specifies
143the class that contains the main method. (You may have noticed that our example
dzc205125b2017-06-26 11:01:47 +0200144uses [glob](../be/functions.html#glob) to pass a set of source files to Bazel
Googler8af9dc52017-06-07 13:49:48 -0400145instead of listing them one by one.)
dzc22b85a22017-05-31 20:37:50 +0200146
Googler8af9dc52017-06-07 13:49:48 -0400147### Build the project
dzc22b85a22017-05-31 20:37:50 +0200148
Googler8af9dc52017-06-07 13:49:48 -0400149Let's build your sample project. Change into the `java-tutorial` directory
150and run the following command:
dzc22b85a22017-05-31 20:37:50 +0200151
Googler8af9dc52017-06-07 13:49:48 -0400152```
Googler006659e2017-07-20 19:48:05 +0200153bazel build //:ProjectRunner
Googler8af9dc52017-06-07 13:49:48 -0400154```
155Notice the target label - the `//` part is the location of our `BUILD` file
156relative to the root of the workspace (in this case, the root itself), and
157`ProjectRunner` is what we named that target in the `BUILD` file. (You will
158learn about target labels in more detail at the end of this tutorial.)
dzc22b85a22017-05-31 20:37:50 +0200159
Googler8af9dc52017-06-07 13:49:48 -0400160Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200161
Googler8af9dc52017-06-07 13:49:48 -0400162```bash
Googler006659e2017-07-20 19:48:05 +0200163 INFO: Found 1 target...
164 Target //:ProjectRunner up-to-date:
165 bazel-bin/ProjectRunner.jar
166 bazel-bin/ProjectRunner
167 INFO: Elapsed time: 1.021s, Critical Path: 0.83s
Googler8af9dc52017-06-07 13:49:48 -0400168```
dzc22b85a22017-05-31 20:37:50 +0200169
Googler8af9dc52017-06-07 13:49:48 -0400170Congratulations, you just built your first Bazel target! Bazel places build
171outputs in the `bazel-bin` directory at the root of the workspace. Browse
172through its contents to get an idea for Bazel's output structure.
dzc22b85a22017-05-31 20:37:50 +0200173
Googler8af9dc52017-06-07 13:49:48 -0400174Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200175
dzc51dcd282017-06-14 22:52:27 +0200176```sh
Googler8af9dc52017-06-07 13:49:48 -0400177bazel-bin/ProjectRunner
178```
dzc22b85a22017-05-31 20:37:50 +0200179
180### Review the dependency graph
181
Googler8af9dc52017-06-07 13:49:48 -0400182Bazel requires build dependencies to be explicitly declared in BUILD files.
183Bazel uses those statements to create the project's dependency graph, which
184enables accurate incremental builds.
dzc22b85a22017-05-31 20:37:50 +0200185
Googler8af9dc52017-06-07 13:49:48 -0400186Let's visualize our sample project's dependencies. First, generate a text
187representation of the dependency graph (run the command at the workspace root):
dzc22b85a22017-05-31 20:37:50 +0200188
Googler8af9dc52017-06-07 13:49:48 -0400189```
pcloudy22f16e42018-08-31 08:11:48 -0700190bazel query --nohost_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
Googler8af9dc52017-06-07 13:49:48 -0400191```
dzc22b85a22017-05-31 20:37:50 +0200192
Googler8af9dc52017-06-07 13:49:48 -0400193The above command tells Bazel to look for all dependencies for the target
194`//:ProjectRunner` (excluding host and implicit dependencies) and format the
195output as a graph.
dzc22b85a22017-05-31 20:37:50 +0200196
Googler8af9dc52017-06-07 13:49:48 -0400197Then, paste the text into [GraphViz](http://www.webgraphviz.com/).
dzc22b85a22017-05-31 20:37:50 +0200198
dzc22b85a22017-05-31 20:37:50 +0200199
Googler8af9dc52017-06-07 13:49:48 -0400200As you can see, the project has a single target that build two source files with
201no additional dependencies:
dzc22b85a22017-05-31 20:37:50 +0200202
Googler8af9dc52017-06-07 13:49:48 -0400203![Dependency graph of the target 'ProjectRunner'](/assets/tutorial_java_01.svg)
dzc22b85a22017-05-31 20:37:50 +0200204
Googler8af9dc52017-06-07 13:49:48 -0400205Now that you have set up your workspace, built your project, and examined its
206dependencies, let's add some complexity.
dzc22b85a22017-05-31 20:37:50 +0200207
208## Refine your Bazel build
209
Googler8af9dc52017-06-07 13:49:48 -0400210While a single target is sufficient for small projects, you may want to split
211larger projects into multiple targets and packages to allow for fast incremental
212builds (that is, only rebuild what's changed) and to speed up your builds by
213building multiple parts of a project at once.
dzc22b85a22017-05-31 20:37:50 +0200214
Googler8af9dc52017-06-07 13:49:48 -0400215### Specify multiple build targets
dzc22b85a22017-05-31 20:37:50 +0200216
Googler8af9dc52017-06-07 13:49:48 -0400217Let's split our sample project build into two targets. Replace the contents of
218the `java-tutorial/BUILD` file with the following:
dzc22b85a22017-05-31 20:37:50 +0200219
Googler8af9dc52017-06-07 13:49:48 -0400220```
221java_binary(
222 name = "ProjectRunner",
223 srcs = ["src/main/java/com/example/ProjectRunner.java"],
224 main_class = "com.example.ProjectRunner",
225 deps = [":greeter"],
226)
dzc22b85a22017-05-31 20:37:50 +0200227
Googler8af9dc52017-06-07 13:49:48 -0400228java_library(
229 name = "greeter",
230 srcs = ["src/main/java/com/example/Greeting.java"],
231)
232```
dzc22b85a22017-05-31 20:37:50 +0200233
Googler8af9dc52017-06-07 13:49:48 -0400234With this configuration, Bazel first builds the `greeter` library, then the
Passw473a9162017-12-22 14:13:12 -0800235`ProjectRunner` binary. The `deps` attribute in `java_binary` tells Bazel that
Googler8af9dc52017-06-07 13:49:48 -0400236the `greeter` library is required to build the `ProjectRunner` binary.
dzc22b85a22017-05-31 20:37:50 +0200237
Googler8af9dc52017-06-07 13:49:48 -0400238Let's build this new version of our project. Run the following command:
dzc22b85a22017-05-31 20:37:50 +0200239
Googler8af9dc52017-06-07 13:49:48 -0400240```
241bazel build //:ProjectRunner
242```
dzc22b85a22017-05-31 20:37:50 +0200243
Googler8af9dc52017-06-07 13:49:48 -0400244Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200245
Googler8af9dc52017-06-07 13:49:48 -0400246```
247INFO: Found 1 target...
248Target //:ProjectRunner up-to-date:
249 bazel-bin/ProjectRunner.jar
250 bazel-bin/ProjectRunner
251INFO: Elapsed time: 2.454s, Critical Path: 1.58s
252```
dzc22b85a22017-05-31 20:37:50 +0200253
Googler8af9dc52017-06-07 13:49:48 -0400254Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200255
Googler8af9dc52017-06-07 13:49:48 -0400256```
257bazel-bin/ProjectRunner
258```
dzc22b85a22017-05-31 20:37:50 +0200259
Googler8af9dc52017-06-07 13:49:48 -0400260If you now modify `ProjectRunner.java` and rebuild the project, Bazel only
261recompiles that file.
dzc22b85a22017-05-31 20:37:50 +0200262
Googler8af9dc52017-06-07 13:49:48 -0400263Looking at the dependency graph, you can see that `ProjectRunner` depends on the
264same inputs as it did before, but the structure of the build is different:
dzc22b85a22017-05-31 20:37:50 +0200265
Googler8af9dc52017-06-07 13:49:48 -0400266![Dependency graph of the target 'ProjectRunner' after adding a dependency]
267(/assets/tutorial_java_02.svg)
dzc22b85a22017-05-31 20:37:50 +0200268
Googler8af9dc52017-06-07 13:49:48 -0400269You've now built the project with two targets. The `ProjectRunner` target builds
270two source files and depends on one other target (`:greeter`), which builds
271one additional source file.
dzc22b85a22017-05-31 20:37:50 +0200272
273### Use multiple packages
274
Googler8af9dc52017-06-07 13:49:48 -0400275Lets now split the project into multiple packages. If you take a look at the
276`src/main/java/com/example/cmdline` directory, you can see that it also contains
277a `BUILD` file, plus some source files. Therefore, to Bazel, the workspace now
278contains two packages, `//src/main/java/com/example/cmdline` and `//` (since
279there is a `BUILD` file at the root of the workspace).
dzc22b85a22017-05-31 20:37:50 +0200280
Googler8af9dc52017-06-07 13:49:48 -0400281Take a look at the `src/main/java/com/example/cmdline/BUILD` file:
dzc22b85a22017-05-31 20:37:50 +0200282
Googler8af9dc52017-06-07 13:49:48 -0400283```
284java_binary(
285 name = "runner",
286 srcs = ["Runner.java"],
287 main_class = "com.example.cmdline.Runner",
288 deps = ["//:greeter"]
289)
290```
dzc22b85a22017-05-31 20:37:50 +0200291
Googler8af9dc52017-06-07 13:49:48 -0400292The `runner` target depends on the `greeter` target in the `//` package (hence
293the target label `//:greeter`) - Bazel knows this through the `deps` attribute.
294Take a look at the dependency graph:
dzc22b85a22017-05-31 20:37:50 +0200295
Googler8af9dc52017-06-07 13:49:48 -0400296![Dependency graph of the target 'runner'](/assets/tutorial_java_03.svg)
dzc22b85a22017-05-31 20:37:50 +0200297
Peter Laird4b16e022017-10-12 16:44:19 +0200298However, for the build to succeed, you must explicitly give the `runner` target in
299`//src/main/java/com/example/cmdline/BUILD` visibility to targets in
Googler8af9dc52017-06-07 13:49:48 -0400300`//BUILD` using the `visibility` attribute. This is because by default targets
301are only visible to other targets in the same `BUILD` file. (Bazel uses target
302visibility to prevent issues such as libraries containing implementation details
303leaking into public APIs.)
dzc22b85a22017-05-31 20:37:50 +0200304
Googler8af9dc52017-06-07 13:49:48 -0400305To do this, add the `visibility` attribute to the `greeter` target in
306`java-tutorial/BUILD` as shown below:
dzc22b85a22017-05-31 20:37:50 +0200307
Googler8af9dc52017-06-07 13:49:48 -0400308```
309java_library(
310 name = "greeter",
311 srcs = ["src/main/java/com/example/Greeting.java"],
312 visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
dzc22b85a22017-05-31 20:37:50 +0200313 )
Googler8af9dc52017-06-07 13:49:48 -0400314```
dzc22b85a22017-05-31 20:37:50 +0200315
Googler8af9dc52017-06-07 13:49:48 -0400316Let's now build the new package. Run the following command at the root of the
317workspace:
dzc22b85a22017-05-31 20:37:50 +0200318
Googler8af9dc52017-06-07 13:49:48 -0400319```
320bazel build //src/main/java/com/example/cmdline:runner
321```
dzc22b85a22017-05-31 20:37:50 +0200322
Googler8af9dc52017-06-07 13:49:48 -0400323Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200324
Googler8af9dc52017-06-07 13:49:48 -0400325```
326INFO: Found 1 target...
327Target //src/main/java/com/example/cmdline:runner up-to-date:
328 bazel-bin/src/main/java/com/example/cmdline/runner.jar
329 bazel-bin/src/main/java/com/example/cmdline/runner
330 INFO: Elapsed time: 1.576s, Critical Path: 0.81s
331```
dzc22b85a22017-05-31 20:37:50 +0200332
Googler8af9dc52017-06-07 13:49:48 -0400333Now test your freshly built binary:
dzc22b85a22017-05-31 20:37:50 +0200334
Googler8af9dc52017-06-07 13:49:48 -0400335```
336./bazel-bin/src/main/java/com/example/cmdline/runner
dzc22b85a22017-05-31 20:37:50 +0200337
Googler8af9dc52017-06-07 13:49:48 -0400338```
dzc22b85a22017-05-31 20:37:50 +0200339
Googler8af9dc52017-06-07 13:49:48 -0400340You've now modified the project to build as two packages, each containing one
341target, and understand the dependencies between them.
dzc22b85a22017-05-31 20:37:50 +0200342
dzc22b85a22017-05-31 20:37:50 +0200343
344## Use labels to reference targets
345
Googler8af9dc52017-06-07 13:49:48 -0400346In `BUILD` files and at the command line, Bazel uses target labels to reference
347targets - for example, `//:ProjectRunner` or
348`//src/main/java/com/example/cmdline:runner`. Their syntax is as follows:
dzc22b85a22017-05-31 20:37:50 +0200349
350```
Googler8af9dc52017-06-07 13:49:48 -0400351//path/to/package:target-name
dzc22b85a22017-05-31 20:37:50 +0200352```
353
Googler8af9dc52017-06-07 13:49:48 -0400354If the target is a rule target, then `path/to/package` is the path to the
355directory containing the `BUILD` file, and `target-name` is what you named the
356target in the `BUILD` file (the `name` attribute). If the target is a file
357target, then `path/to/package` is the path to the root of the package, and
358`target-name` is the name of the target file, including its full path.
dzc22b85a22017-05-31 20:37:50 +0200359
Googler8af9dc52017-06-07 13:49:48 -0400360When referencing targets within the same package, you can skip the package path
361and just use `//:target-name`. When referencing targets within the same `BUILD`
362file, you can even skip the `//` workspace root identifier and just use
363`:target-name`.
dzc22b85a22017-05-31 20:37:50 +0200364
Googler8af9dc52017-06-07 13:49:48 -0400365For example, for targets in the `java-tutorial/BUILD` file, you did not have to
366specify a package path, since the workspace root is itself a package (`//`), and
367your two target labels were simply `//:ProjectRunner` and `//:greeter`.
dzc22b85a22017-05-31 20:37:50 +0200368
Googler8af9dc52017-06-07 13:49:48 -0400369However, for targets in the `//src/main/java/com/example/cmdline/BUILD` file you
370had to specify the full package path of `//src/main/java/com/example/cmdline`
371and your target label was `//src/main/java/com/example/cmdline:runner`.
dzc22b85a22017-05-31 20:37:50 +0200372
373## Package a Java target for deployment
374
Googler8af9dc52017-06-07 13:49:48 -0400375Lets now package a Java target for deployment by building the binary with all
376of its runtime dependencies. This lets you run the binary outside of your
377development environment.
dzc22b85a22017-05-31 20:37:50 +0200378
dzc205125b2017-06-26 11:01:47 +0200379As you remember, the [java_binary](../be/java.html#java_binary) build rule
Googler8af9dc52017-06-07 13:49:48 -0400380produces a `.jar` and a wrapper shell script. Take a look at the contents of
381`runner.jar` using this command:
dzc22b85a22017-05-31 20:37:50 +0200382
Googler8af9dc52017-06-07 13:49:48 -0400383```
384jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
385```
dzc22b85a22017-05-31 20:37:50 +0200386
Googler8af9dc52017-06-07 13:49:48 -0400387The contents are:
dzc22b85a22017-05-31 20:37:50 +0200388
Googler8af9dc52017-06-07 13:49:48 -0400389```
390META-INF/
391META-INF/MANIFEST.MF
392com/
393com/example/
394com/example/cmdline/
395com/example/cmdline/Runner.class
396```
397As you can see, `runner.jar` contains `Runner.class`, but not its dependency,
398`Greeting.class`. The `runner` script that Bazel generates adds `greeter.jar`
399to the classpath, so if you leave it like this, it will run locally, but it
400won't run standalone on another machine. Fortunately, the `java_binary` rule
401allows you to build a self-contained, deployable binary. To build it, add the
402`_deploy.jar` suffix to the file name when building `runner.jar`
403(<target-name>_deploy.jar):
dzc22b85a22017-05-31 20:37:50 +0200404
Googler8af9dc52017-06-07 13:49:48 -0400405```
406bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
407```
dzc22b85a22017-05-31 20:37:50 +0200408
Googler8af9dc52017-06-07 13:49:48 -0400409Bazel produces output similar to the following:
dzc22b85a22017-05-31 20:37:50 +0200410
Googler8af9dc52017-06-07 13:49:48 -0400411```
412INFO: Found 1 target...
413Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
414 bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
415INFO: Elapsed time: 1.700s, Critical Path: 0.23s
416```
417You have just built `runner_deploy.jar`, which you can run standalone away from
418your development environment since it contains the required runtime
419dependencies.
dzc22b85a22017-05-31 20:37:50 +0200420
Googler8af9dc52017-06-07 13:49:48 -0400421## Further reading
dzc22b85a22017-05-31 20:37:50 +0200422
dzc205125b2017-06-26 11:01:47 +0200423* [External Dependencies](../external.html) to learn more about working with
424 local and remote repositories.
dzc22b85a22017-05-31 20:37:50 +0200425
dzc205125b2017-06-26 11:01:47 +0200426* The [Build Encyclopedia](../be/overview.html) to learn more about Bazel.
dzc22b85a22017-05-31 20:37:50 +0200427
dzc205125b2017-06-26 11:01:47 +0200428* The [C++ build tutorial](../tutorial/cpp.md) to get started with building
Googler8af9dc52017-06-07 13:49:48 -0400429 C++ projects with Bazel.
dzc22b85a22017-05-31 20:37:50 +0200430
Laszlo Csomor5d357942018-06-12 01:56:45 -0700431* The [Android application tutorial](../tutorial/android-app.md) and
432 [iOS application tutorial](../tutorial/ios-app.md) to get started with
Googler8af9dc52017-06-07 13:49:48 -0400433 building mobile applications for Android and iOS with Bazel.
dzc22b85a22017-05-31 20:37:50 +0200434
Googler8af9dc52017-06-07 13:49:48 -0400435Happy building!
dzc22b85a22017-05-31 20:37:50 +0200436