blob: 20db3e2ac81f787ba728d3e50f96a16bd5798244 [file] [log] [blame] [view]
David Chenc4af8282016-01-20 11:06:35 +00001---
dzc22b85a22017-05-31 20:37:50 +02002layout: documentation
Googler3d70c312017-08-09 00:23:38 +02003title: Build Tutorial - Android
David Chenc4af8282016-01-20 11:06:35 +00004---
dzc22b85a22017-05-31 20:37:50 +02005
ahumesky71c14412017-12-08 11:55:53 -08006Introduction to Bazel: Building an Android App
Googler3d70c312017-08-09 00:23:38 +02007==========
dzc22b85a22017-05-31 20:37:50 +02008
Googler3d70c312017-08-09 00:23:38 +02009In this tutorial, you will learn how to build a simple Android app. You'll do
10the following:
dzc22b85a22017-05-31 20:37:50 +020011
Googler3d70c312017-08-09 00:23:38 +020012* [Set up your environment](#set-up-your-environment)
13 * [Install Bazel](#install-bazel)
14 * [Install Android Studio](#install-android-studio)
15 * [Get the sample project](#get-the-sample-project)
16* [Set up a workspace](#set-up-a-workspace)
17 * [Create a WORKSPACE file](#create-a-workspace-file)
18 * [Update the WORKSPACE file](#update-the-workspace-file)
19* [Review the source files](#review-the-source-files)
20* [Create a BUILD file](#create-a-build-file)
21 * [Add an android_library rule](#add-an-android_library-rule)
22 * [Add an android_binary rule](#add_an-android_binary-rule)
23* [Build the app](#build-the-app)
24* [Find the build outputs](#find-the-build-outputs)
25* [Run the app](#run-the-app)
26* [Review your work](#review-your-work)
dzc22b85a22017-05-31 20:37:50 +020027
Googler3d70c312017-08-09 00:23:38 +020028## Set up your environment
29
30To get started, install Bazel and Android Studio, and get the sample project.
31
32### Install Bazel
33
34Follow the [installation instructions](../install.md) to install Bazel and
35its dependencies.
36
37### Install Android Studio
38
39Download and install Android Studio as described in [Install Android Studio](https://developer.android.com/sdk/index.html).
40
41The installer does not automatically set the `ANDROID_HOME` variable.
42Set it to the location of the Android SDK, which defaults to `$HOME/Android/Sdk/`
43.
44
45For example:
46
47`export ANDROID_HOME=$HOME/Android/Sdk/`
48
49For convenience, add the above statement to your `~/.bashrc` file.
50
51### Get the sample project
52
53You also need to get the sample project for the tutorial from GitHub. The repo
54has two branches: `source-only` and `master`. The `source-only` branch contains
55the source files for the project only. You'll use the files in this branch in
56this tutorial. The `master` branch contains both the source files and completed
57Bazel `WORKSPACE` and `BUILD` files. You can use the files in this branch to
58check your work when you've completed the tutorial steps.
59
60Enter the following at the command line to get the files in the `source-only`
61branch:
62
63```bash
64cd $HOME
65git clone -b source-only https://github.com/bazelbuild/examples
66```
67
68The `git clone` command creates a directory named `$HOME/examples/`. This
69directory contains several sample projects for Bazel. The project files for this
70tutorial are in `$HOME/examples/tutorial/android`.
71
72## Set up a workspace
73
74A [workspace](../build-ref.html#workspaces) is a directory that contains the
75source files for one or more software projects, as well as a `WORKSPACE` file
76and `BUILD` files that contain the instructions that Bazel uses to build
77the software. The workspace may also contain symbolic links to output
78directories.
79
80A workspace directory can be located anywhere on your filesystem and is denoted
81by the presence of the `WORKSPACE` file at its root. In this tutorial, your
82workspace directory is `$HOME/examples/tutorial/`, which contains the sample
83project files you cloned from the GitHub repo in the previous step.
84
85Note that Bazel itself doesn't make any requirements about how you organize
86source files in your workspace. The sample source files in this tutorial are
87organized according to conventions for the target platform.
88
89For your convenience, set the `$WORKSPACE` environment variable now to refer to
90your workspace directory. At the command line, enter:
91
92```bash
93export WORKSPACE=$HOME/examples/tutorial
94```
95
96### Create a WORKSPACE file
97
98Every workspace must have a text file named `WORKSPACE` located in the top-level
99workspace directory. This file may be empty or it may contain references
100to [external dependencies](../external.html) required to build the
101software.
102
103For now, you'll create an empty `WORKSPACE` file, which simply serves to
104identify the workspace directory. In later steps, you'll update the file to add
105external dependency information.
106
107Enter the following at the command line:
108
109```bash
110touch $WORKSPACE/WORKSPACE
111```
112This creates the empty `WORKSPACE` file.
113
114### Update the WORKSPACE file
115
116Bazel needs to run the Android SDK
117[build tools](https://developer.android.com/tools/revisions/build-tools.html)
118and uses the SDK libraries to build the app. This means that you need to add
119some information to your `WORKSPACE` file so that Bazel knows where to find
120them. Note that this step is not required when you build for other platforms.
121For example, Bazel automatically detects the location of Java, C++ and
122Objective-C compilers from settings in your environment.
123
124Add the following lines to your `WORKSPACE` file:
125
126```python
127android_sdk_repository(
dannark5eb684f2017-09-06 02:29:30 +0200128 name = "androidsdk"
Googler3d70c312017-08-09 00:23:38 +0200129)
130```
131
132This will use the Android SDK referenced by the `ANDROID_HOME` environment
dannark5eb684f2017-09-06 02:29:30 +0200133variable, and automatically detect the highest API level and the latest version
134of build tools installed within that location.
Googler3d70c312017-08-09 00:23:38 +0200135
136Alternatively, you can explicitly specify the location of the Android
dannark5eb684f2017-09-06 02:29:30 +0200137SDK, the API level, and the version of build tools to use by including the
138`path`,`api_level`, and `build_tools_version` attributes. You can specify any
139subset of these attributes:
Googler3d70c312017-08-09 00:23:38 +0200140
141```python
142android_sdk_repository(
143 name = "androidsdk",
144 path = "/path/to/Android/sdk",
145 api_level = 25,
dannark5eb684f2017-09-06 02:29:30 +0200146 build_tools_version = "26.0.1"
Googler3d70c312017-08-09 00:23:38 +0200147)
148```
149
150**Optional:** This is not required by this tutorial, but if you want to compile
151native code into your Android app, you also need to download the
152[Android NDK](https://developer.android.com/ndk/downloads/index.html) and
153tell Bazel where to find it by adding the following rule to your `WORKSPACE`
154file:
155
156```python
157android_ndk_repository(
dannark5eb684f2017-09-06 02:29:30 +0200158 name = "androidndk"
Googler3d70c312017-08-09 00:23:38 +0200159)
160```
161
162`api_level` is the version of the Android API the SDK and the NDK target
dannark5eb684f2017-09-06 02:29:30 +0200163(for example, 23 for Android 6.0 and 25 for Android 7.1). If not explicitly
164set, `api_level` will default to the highest available API level for
165`android_sdk_repository` and `android_ndk_repository`. It's not necessary to
Googler3d70c312017-08-09 00:23:38 +0200166set the API levels to the same value for the SDK and NDK.
167[This web page](https://developer.android.com/ndk/guides/stable_apis.html)
168contains a map from Android releases to NDK-supported API levels.
169
170Similar to `android_sdk_repository`, the path to the Android NDK is inferred
171from the `ANDROID_NDK_HOME` environment variable by default. The path can also
172be explicitly specified with a `path` attribute on `android_ndk_repository`.
dzc22b85a22017-05-31 20:37:50 +0200173
174## Review the source files
175
176Let's take a look at the source files for the app. These are located in
177`$WORKSPACE/android/`.
178
179The key files and directories are:
180
181<table class="table table-condensed table-striped">
182<thead>
183<tr>
184<td>Name</td>
185<td>Location</td>
186</tr>
187</thead>
188<tbody>
189<tr>
190<td>Manifest file</td>
191<td><code>src/main/java/com/google/bazel/example/android/AndroidManifest.xml</code></td>
192</tr>
193<tr>
194<td>Activity source file</td>
195<td><code>src/main/java/com/google/bazel/example/android/activities/MainActivity.java</code></td>
196</tr>
197<tr>
198<td>Resource file directory</td>
199<td><code>src/main/java/com/google/bazel/example/android/res/</code></td>
200</tr>
201</tbody>
202</table>
203
204Note that you're just looking at these files now to become familiar with the
205structure of the app. You don't have to edit any of the source files to complete
206this tutorial.
207
dzc22b85a22017-05-31 20:37:50 +0200208## Create a BUILD file
209
dzc205125b2017-06-26 11:01:47 +0200210A [`BUILD` file](../build-ref.html#BUILD_files) is a text file that describes
dzc22b85a22017-05-31 20:37:50 +0200211the relationship between a set of build outputs -- for example, compiled
212software libraries or executables -- and their dependencies. These dependencies
213may be source files in your workspace or other build outputs. `BUILD` files are
214written in the Bazel *build language*.
215
Googler3d70c312017-08-09 00:23:38 +0200216`BUILD` files are part of a concept in Bazel known as the *package hierarchy*.
dzc22b85a22017-05-31 20:37:50 +0200217The package hierarchy is a logical structure that overlays the directory
dzc205125b2017-06-26 11:01:47 +0200218structure in your workspace. Each [package](../build-ref.html#packages) is a
dzc22b85a22017-05-31 20:37:50 +0200219directory (and its subdirectories) that contains a related set of source files
220and a `BUILD` file. The package also includes any subdirectories, excluding
221those that contain their own `BUILD` file. The *package name* is the name of the
222directory where the `BUILD` file is located.
223
224Note that this package hierarchy is distinct from, but coexists with, the Java
225package hierarchy for your Android app.
226
227For the simple Android app in this tutorial, we'll consider all the source files
228in `$WORKSPACE/android/` to comprise a single Bazel package. A more complex
229project may have many nested packages.
230
231At a command-line prompt, open your new `BUILD` file for editing:
232
233```bash
234vi $WORKSPACE/android/BUILD
235```
236
237### Add an android_library rule
238
239A `BUILD` file contains several different types of instructions for Bazel. The
dzc205125b2017-06-26 11:01:47 +0200240most important type is the [build rule](../build-ref.html#funcs), which tells
dzc22b85a22017-05-31 20:37:50 +0200241Bazel how to build an intermediate or final software output from a set of source
242files or other dependencies.
243
244Bazel provides two build rules, `android_library` and `android_binary`, that you
245can use to build an Android app. For this tutorial, you'll first use the
dzc205125b2017-06-26 11:01:47 +0200246[`android_library`](../be/android.html#android_library) rule to tell
dzc22b85a22017-05-31 20:37:50 +0200247Bazel how to build an
248[Android library module](http://developer.android.com/tools/projects/index.html#LibraryProjects)
249from the app source code and resource files. Then you'll use the
250`android_binary` rule to tell it how to build the Android application package.
251
252Add the following to your `BUILD` file:
253
254```python
255android_library(
256 name = "activities",
257 srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]),
258 custom_package = "com.google.bazel.example.android.activities",
259 manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml",
260 resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]),
261)
262```
263
264As you can see, the `android_library` build rule contains a set of attributes
265that specify the information that Bazel needs to build a library module from the
266source files. Note also that the name of the rule is `activities`. You'll
267reference the rule using this name as a dependency in the `android_binary` rule.
268
269### Add an android_binary rule
270
dzc205125b2017-06-26 11:01:47 +0200271The [`android_binary`](../be/android.html#android_binary) rule builds
dzc22b85a22017-05-31 20:37:50 +0200272the Android application package (`.apk` file) for your app.
273
274Add the following to your build file:
275
276```python
277android_binary(
278 name = "android",
279 custom_package = "com.google.bazel.example.android",
280 manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml",
281 resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]),
282 deps = [":activities"],
283)
284```
285
286Here, the `deps` attribute references the output of the `activities` rule you
287added to the `BUILD` file above. This means that, when Bazel builds the output
288of this rule, it checks first to see if the output of the `activities` library
289rule has been built and is up-to-date. If not, it builds it and then uses that
290output to build the application package file.
291
292Now, save and close the file. You can compare your `BUILD` file to the
293[completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/android/BUILD)
294in the `master` branch of the GitHub repo.
295
Googler3d70c312017-08-09 00:23:38 +0200296## Build the app
dzc22b85a22017-05-31 20:37:50 +0200297
298You use the
dmartingcdb8a632017-09-04 11:43:35 +0200299[`bazel`](../user-manual.html) command-line tool to run builds, execute
dzc22b85a22017-05-31 20:37:50 +0200300unit tests and perform other operations in Bazel. This tool is located in the
301`output` subdirectory of the location where you installed Bazel. During
dzc205125b2017-06-26 11:01:47 +0200302[installation](../install.md), you probably added this location to your
dzc22b85a22017-05-31 20:37:50 +0200303path.
304
305Before you build the sample app, make sure that your current working directory
306is inside your Bazel workspace:
307
308```bash
309cd $WORKSPACE
310```
311
312Now, enter the following to build the sample app:
313
314```bash
315bazel build //android:android
316```
317
Jingwen Chen7633ab02018-03-05 09:30:14 -0800318The [`build`](../user-manual.html#build) subcommand instructs Bazel to
dzc22b85a22017-05-31 20:37:50 +0200319build the target that follows. The target is specified as the name of a build
320rule inside a `BUILD` file, with along with the package path relative to
321your workspace directory. Note that you can sometimes omit the package path
322or target name, depending on your current working directory at the command
Googler3d70c312017-08-09 00:23:38 +0200323line and the name of the target. See [Labels](../build-ref.html#labels) in the
dzc22b85a22017-05-31 20:37:50 +0200324*Bazel Concepts and Terminology* page for more information about target labels
325and paths.
326
327Bazel now launches and builds the sample app. During the build process, its
328output will appear similar to the following:
329
330```bash
331INFO: Found 1 target...
332Target //android:android up-to-date:
333 bazel-bin/android/android_deploy.jar
334 bazel-bin/android/android_unsigned.apk
335 bazel-bin/android/android.apk
336INFO: Elapsed time: 7.237s, Critical Path: 5.81s
337```
338
339## Find the build outputs
340
341Bazel stores the outputs of both intermediate and final build operations in
342a set of per-user, per-workspace output directories. These directories are
343symlinked from the following locations:
344
345* `$WORKSPACE/bazel-bin`, which stores binary executables and other runnable
346 build outputs
347* `$WORKSPACE/bazel-genfiles`, which stores intermediary source files that are
348 generated by Bazel rules
349* `$WORKSPACE/bazel-out`, which stores other types of build outputs
350
351Bazel stores the Android `.apk` file generated using the `android_binary` rule
352in the `bazel-bin/android/` directory, where the subdirectory name `android` is
353derived from the name of the Bazel package.
354
355At a command prompt, list the contents of this directory and find the
356`android.apk` file:
357
358```bash
359ls $WORKSPACE/bazel-bin/android
360```
361
362## Run the app
363
Googler3d70c312017-08-09 00:23:38 +0200364**NOTE:** The app launches standalone but requires a backend server in order to
365produce output. See the README file in the sample project directory to find out
366how to build the backend server.
367
dzc22b85a22017-05-31 20:37:50 +0200368You can now deploy the app to a connected Android device or emulator from the
369command line using the
Jingwen Chen7633ab02018-03-05 09:30:14 -0800370[`bazel mobile-install`](../user-manual.html#mobile-install)
dzc22b85a22017-05-31 20:37:50 +0200371command. This command uses the Android Debug Bridge (`adb`) to communicate with
372the device. You must set up your device to use `adb` following the instructions
373in
374[Android Debug Bridge](http://developer.android.com/tools/help/adb.html) before
Googlerb343cda2017-06-07 14:45:17 -0400375deployment. You can also choose to install the app on the Android emulator
376included in Android Studio. Make sure the emulator is running before executing
377the command below.
dzc22b85a22017-05-31 20:37:50 +0200378
379Enter the following:
380
381```bash
382bazel mobile-install //android:android
383```
384
385Note that the `mobile-install` subcommand also supports the
Jingwen Chen7633ab02018-03-05 09:30:14 -0800386[`--incremental`](../user-manual.html#mobile-install)
dzc22b85a22017-05-31 20:37:50 +0200387flag that can be used to deploy only those parts of the app that have changed
388since the last deployment.
389
Googler3d70c312017-08-09 00:23:38 +0200390## Review your work
dzc22b85a22017-05-31 20:37:50 +0200391
Googler3d70c312017-08-09 00:23:38 +0200392In this tutorial, you used Bazel to build an Android app. To accomplish that,
393you:
394
395* Set up your environment by installing Bazel and Android Studio, and
396 downloading the sample project
397* Set up a Bazel [workspace](workspace.md) that contained the source code
398 for the app and a `WORKSPACE` file that identifies the top level of the
399 workspace directory
400* Updated the `WORKSPACE` file to contain references to the required
401 external dependencies
402* Created a `BUILD` file
403* Ran Bazel to build the app
404* Deployed and ran the app on an Android emulator and device
405
406The built app is located in the `$WORKSPACE/bazel-bin` directory.
407
408Note that completed `WORKSPACE` and `BUILD` files for this tutorial are located
409in the
410[master branch](https://github.com/bazelbuild/examples/tree/master/tutorial)
411of the GitHub repo. You can compare your work to the completed files for
412additional help or troubleshooting.