--- layout: documentation title: Build Tutorial - Android --- Introduction to Bazel: Building an Android App ========== In this tutorial, you will learn how to build a simple Android app. You'll do the following: * [Set up your environment](#set-up-your-environment) * [Install Bazel](#install-bazel) * [Install Android Studio](#install-android-studio) * [Get the sample project](#get-the-sample-project) * [Set up a workspace](#set-up-a-workspace) * [Create a WORKSPACE file](#create-a-workspace-file) * [Update the WORKSPACE file](#update-the-workspace-file) * [Review the source files](#review-the-source-files) * [Create a BUILD file](#create-a-build-file) * [Add an android_library rule](#add-an-android_library-rule) * [Add an android_binary rule](#add_an-android_binary-rule) * [Build the app](#build-the-app) * [Find the build outputs](#find-the-build-outputs) * [Run the app](#run-the-app) * [Review your work](#review-your-work) ## Set up your environment To get started, install Bazel and Android Studio, and get the sample project. ### Install Bazel Follow the [installation instructions](../install.md) to install Bazel and its dependencies. ### Install Android Studio Download and install Android Studio as described in [Install Android Studio](https://developer.android.com/sdk/index.html). The installer does not automatically set the `ANDROID_HOME` variable. Set it to the location of the Android SDK, which defaults to `$HOME/Android/Sdk/` . For example: `export ANDROID_HOME=$HOME/Android/Sdk/` For convenience, add the above statement to your `~/.bashrc` file. ### Get the sample project You also need to get the sample project for the tutorial from GitHub. The repo has two branches: `source-only` and `master`. The `source-only` branch contains the source files for the project only. You'll use the files in this branch in this tutorial. The `master` branch contains both the source files and completed Bazel `WORKSPACE` and `BUILD` files. You can use the files in this branch to check your work when you've completed the tutorial steps. Enter the following at the command line to get the files in the `source-only` branch: ```bash cd $HOME git clone -b source-only https://github.com/bazelbuild/examples ``` The `git clone` command creates a directory named `$HOME/examples/`. This directory contains several sample projects for Bazel. The project files for this tutorial are in `$HOME/examples/tutorial/android`. ## Set up a workspace A [workspace](../build-ref.html#workspaces) is a directory that contains the source files for one or more software projects, as well as a `WORKSPACE` file and `BUILD` files that contain the instructions that Bazel uses to build the software. The workspace may also contain symbolic links to output directories. A workspace directory can be located anywhere on your filesystem and is denoted by the presence of the `WORKSPACE` file at its root. In this tutorial, your workspace directory is `$HOME/examples/tutorial/`, which contains the sample project files you cloned from the GitHub repo in the previous step. Note that Bazel itself doesn't make any requirements about how you organize source files in your workspace. The sample source files in this tutorial are organized according to conventions for the target platform. For your convenience, set the `$WORKSPACE` environment variable now to refer to your workspace directory. At the command line, enter: ```bash export WORKSPACE=$HOME/examples/tutorial ``` ### Create a WORKSPACE file Every workspace must have a text file named `WORKSPACE` located in the top-level workspace directory. This file may be empty or it may contain references to [external dependencies](../external.html) required to build the software. For now, you'll create an empty `WORKSPACE` file, which simply serves to identify the workspace directory. In later steps, you'll update the file to add external dependency information. Enter the following at the command line: ```bash touch $WORKSPACE/WORKSPACE ``` This creates the empty `WORKSPACE` file. ### Update the WORKSPACE file Bazel needs to run the Android SDK [build tools](https://developer.android.com/tools/revisions/build-tools.html) and uses the SDK libraries to build the app. This means that you need to add some information to your `WORKSPACE` file so that Bazel knows where to find them. Note that this step is not required when you build for other platforms. For example, Bazel automatically detects the location of Java, C++ and Objective-C compilers from settings in your environment. Add the following lines to your `WORKSPACE` file: ```python android_sdk_repository( name = "androidsdk" ) ``` This will use the Android SDK referenced by the `ANDROID_HOME` environment variable, and automatically detect the highest API level and the latest version of build tools installed within that location. Alternatively, you can explicitly specify the location of the Android SDK, the API level, and the version of build tools to use by including the `path`,`api_level`, and `build_tools_version` attributes. You can specify any subset of these attributes: ```python android_sdk_repository( name = "androidsdk", path = "/path/to/Android/sdk", api_level = 25, build_tools_version = "26.0.1" ) ``` **Optional:** This is not required by this tutorial, but if you want to compile native code into your Android app, you also need to download the [Android NDK](https://developer.android.com/ndk/downloads/index.html) and tell Bazel where to find it by adding the following rule to your `WORKSPACE` file: ```python android_ndk_repository( name = "androidndk" ) ``` `api_level` is the version of the Android API the SDK and the NDK target (for example, 23 for Android 6.0 and 25 for Android 7.1). If not explicitly set, `api_level` will default to the highest available API level for `android_sdk_repository` and `android_ndk_repository`. It's not necessary to set the API levels to the same value for the SDK and NDK. [This web page](https://developer.android.com/ndk/guides/stable_apis.html) contains a map from Android releases to NDK-supported API levels. Similar to `android_sdk_repository`, the path to the Android NDK is inferred from the `ANDROID_NDK_HOME` environment variable by default. The path can also be explicitly specified with a `path` attribute on `android_ndk_repository`. ## Review the source files Let's take a look at the source files for the app. These are located in `$WORKSPACE/android/`. The key files and directories are:
Name Location
Manifest file src/main/java/com/google/bazel/example/android/AndroidManifest.xml
Activity source file src/main/java/com/google/bazel/example/android/activities/MainActivity.java
Resource file directory src/main/java/com/google/bazel/example/android/res/
Note that you're just looking at these files now to become familiar with the structure of the app. You don't have to edit any of the source files to complete this tutorial. ## Create a BUILD file A [`BUILD` file](../build-ref.html#BUILD_files) is a text file that describes the relationship between a set of build outputs -- for example, compiled software libraries or executables -- and their dependencies. These dependencies may be source files in your workspace or other build outputs. `BUILD` files are written in the Bazel *build language*. `BUILD` files are part of a concept in Bazel known as the *package hierarchy*. The package hierarchy is a logical structure that overlays the directory structure in your workspace. Each [package](../build-ref.html#packages) is a directory (and its subdirectories) that contains a related set of source files and a `BUILD` file. The package also includes any subdirectories, excluding those that contain their own `BUILD` file. The *package name* is the name of the directory where the `BUILD` file is located. Note that this package hierarchy is distinct from, but coexists with, the Java package hierarchy for your Android app. For the simple Android app in this tutorial, we'll consider all the source files in `$WORKSPACE/android/` to comprise a single Bazel package. A more complex project may have many nested packages. At a command-line prompt, open your new `BUILD` file for editing: ```bash vi $WORKSPACE/android/BUILD ``` ### Add an android_library rule A `BUILD` file contains several different types of instructions for Bazel. The most important type is the [build rule](../build-ref.html#funcs), which tells Bazel how to build an intermediate or final software output from a set of source files or other dependencies. Bazel provides two build rules, `android_library` and `android_binary`, that you can use to build an Android app. For this tutorial, you'll first use the [`android_library`](../be/android.html#android_library) rule to tell Bazel how to build an [Android library module](http://developer.android.com/tools/projects/index.html#LibraryProjects) from the app source code and resource files. Then you'll use the `android_binary` rule to tell it how to build the Android application package. Add the following to your `BUILD` file: ```python android_library( name = "activities", srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]), custom_package = "com.google.bazel.example.android.activities", manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]), ) ``` As you can see, the `android_library` build rule contains a set of attributes that specify the information that Bazel needs to build a library module from the source files. Note also that the name of the rule is `activities`. You'll reference the rule using this name as a dependency in the `android_binary` rule. ### Add an android_binary rule The [`android_binary`](../be/android.html#android_binary) rule builds the Android application package (`.apk` file) for your app. Add the following to your build file: ```python android_binary( name = "android", custom_package = "com.google.bazel.example.android", manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]), deps = [":activities"], ) ``` Here, the `deps` attribute references the output of the `activities` rule you added to the `BUILD` file above. This means that, when Bazel builds the output of this rule, it checks first to see if the output of the `activities` library rule has been built and is up-to-date. If not, it builds it and then uses that output to build the application package file. Now, save and close the file. You can compare your `BUILD` file to the [completed example](https://github.com/bazelbuild/examples/blob/master/tutorial/android/BUILD) in the `master` branch of the GitHub repo. ## Build the app You use the [`bazel`](../user-manual.html) command-line tool to run builds, execute unit tests and perform other operations in Bazel. This tool is located in the `output` subdirectory of the location where you installed Bazel. During [installation](../install.md), you probably added this location to your path. Before you build the sample app, make sure that your current working directory is inside your Bazel workspace: ```bash cd $WORKSPACE ``` Now, enter the following to build the sample app: ```bash bazel build //android:android ``` The [`build`](../user-manual.html#build) subcommand instructs Bazel to build the target that follows. The target is specified as the name of a build rule inside a `BUILD` file, with along with the package path relative to your workspace directory. Note that you can sometimes omit the package path or target name, depending on your current working directory at the command line and the name of the target. See [Labels](../build-ref.html#labels) in the *Bazel Concepts and Terminology* page for more information about target labels and paths. Bazel now launches and builds the sample app. During the build process, its output will appear similar to the following: ```bash INFO: Found 1 target... Target //android:android up-to-date: bazel-bin/android/android_deploy.jar bazel-bin/android/android_unsigned.apk bazel-bin/android/android.apk INFO: Elapsed time: 7.237s, Critical Path: 5.81s ``` ## Find the build outputs Bazel stores the outputs of both intermediate and final build operations in a set of per-user, per-workspace output directories. These directories are symlinked from the following locations: * `$WORKSPACE/bazel-bin`, which stores binary executables and other runnable build outputs * `$WORKSPACE/bazel-genfiles`, which stores intermediary source files that are generated by Bazel rules * `$WORKSPACE/bazel-out`, which stores other types of build outputs Bazel stores the Android `.apk` file generated using the `android_binary` rule in the `bazel-bin/android/` directory, where the subdirectory name `android` is derived from the name of the Bazel package. At a command prompt, list the contents of this directory and find the `android.apk` file: ```bash ls $WORKSPACE/bazel-bin/android ``` ## Run the app **NOTE:** The app launches standalone but requires a backend server in order to produce output. See the README file in the sample project directory to find out how to build the backend server. You can now deploy the app to a connected Android device or emulator from the command line using the [`bazel mobile-install`](../user-manual.html#mobile-install) command. This command uses the Android Debug Bridge (`adb`) to communicate with the device. You must set up your device to use `adb` following the instructions in [Android Debug Bridge](http://developer.android.com/tools/help/adb.html) before deployment. You can also choose to install the app on the Android emulator included in Android Studio. Make sure the emulator is running before executing the command below. Enter the following: ```bash bazel mobile-install //android:android ``` Note that the `mobile-install` subcommand also supports the [`--incremental`](../user-manual.html#mobile-install) flag that can be used to deploy only those parts of the app that have changed since the last deployment. ## Review your work In this tutorial, you used Bazel to build an Android app. To accomplish that, you: * Set up your environment by installing Bazel and Android Studio, and downloading the sample project * Set up a Bazel [workspace](workspace.md) that contained the source code for the app and a `WORKSPACE` file that identifies the top level of the workspace directory * Updated the `WORKSPACE` file to contain references to the required external dependencies * Created a `BUILD` file * Ran Bazel to build the app * Deployed and ran the app on an Android emulator and device The built app is located in the `$WORKSPACE/bazel-bin` directory. Note that completed `WORKSPACE` and `BUILD` files for this tutorial are located in the [master branch](https://github.com/bazelbuild/examples/tree/master/tutorial) of the GitHub repo. You can compare your work to the completed files for additional help or troubleshooting.