Android Rules

android_binary

android_binary(name, deps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, restricted_to, tags, testonly, visibility)

Produces Android application package files (.apk).

Implicit output targets

  • name.apk: An Android application package file signed with debug keys and zipaligned, it could be used to develop and debug your application. You cannot release your application when signed with the debug keys.
  • name_unsigned.apk: An unsigned version of the above file that could be signed with the release keys before release to the public.
  • name_deploy.jar: A Java archive containing the transitive closure of this target.

    The deploy jar contains all the classes that would be found by a classloader that searched the runtime classpath of this target from beginning to end.

  • name_proguard.jar: A Java archive containing the result of running ProGuard on the name_deploy.jar. This output is only produced if proguard_specs attribute is specified.
  • name_proguard.map: A mapping file result of running ProGuard on the name_deploy.jar. This output is only produced if proguard_specs attribute is specified and proguard_generate_mapping or shrink_resources is set.

Examples

Examples of Android rules can be found in the examples/android directory of the Bazel source tree.

Arguments

Attributes
name

Name; required

A unique name for this target.

aar_import

aar_import(name, deps, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, restricted_to, tags, testonly, visibility)

This rule allows the use of .aar files as libraries for android_library and android_binary rules.

Examples

    aar_import(
        name = "google-vr-sdk",
        aar = "gvr-android-sdk/libraries/sdk-common-1.10.0.aar",
    )

    android_binary(
        name = "app",
        manifest = "AndroidManifest.xml",
        srcs = glob(["**.java"]),
        deps = [":google-vr-sdk"],
    )

Arguments

Attributes
name

Name; required

A unique name for this target.

android_library

android_library(name, deps, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, features, licenses, proguard_specs, restricted_to, tags, testonly, visibility)

This rule compiles and archives its sources into a .jar file. The Android runtime library android.jar is implicitly put on the compilation class path.

Implicit output targets

  • libname.jar: A Java archive.
  • libname-src.jar: An archive containing the sources ("source jar").
  • name.aar: An android 'aar' bundle containing the java archive and resources of this target. It does not contain the transitive closure.

Examples

Examples of Android rules can be found in the examples/android directory of the Bazel source tree.

The following example shows how to set idl_import_root. Let //java/bazel/helloandroid/BUILD contain:

android_library(
    name = "parcelable",
    srcs = ["MyParcelable.java"], # bazel.helloandroid.MyParcelable

    # MyParcelable.aidl will be used as import for other .aidl
    # files that depend on it, but will not be compiled.
    idl_parcelables = ["MyParcelable.aidl"] # bazel.helloandroid.MyParcelable

    # We don't need to specify idl_import_root since the aidl file
    # which declares bazel.helloandroid.MyParcelable
    # is present at java/bazel/helloandroid/MyParcelable.aidl
    # underneath a java root (java/).
)

android_library(
    name = "foreign_parcelable",
    srcs = ["src/android/helloandroid/OtherParcelable.java"], # android.helloandroid.OtherParcelable
    idl_parcelables = [
        "src/android/helloandroid/OtherParcelable.aidl" # android.helloandroid.OtherParcelable
    ],

    # We need to specify idl_import_root because the aidl file which
    # declares android.helloandroid.OtherParcelable is not positioned
    # at android/helloandroid/OtherParcelable.aidl under a normal java root.
    # Setting idl_import_root to "src" in //java/bazel/helloandroid
    # adds java/bazel/helloandroid/src to the list of roots
    # the aidl compiler will search for imported types.
    idl_import_root = "src",
)

# Here, OtherInterface.aidl has an "import android.helloandroid.CallbackInterface;" statement.
android_library(
    name = "foreign_interface",
    idl_srcs = [
        "src/android/helloandroid/OtherInterface.aidl" # android.helloandroid.OtherInterface
        "src/android/helloandroid/CallbackInterface.aidl" # android.helloandroid.CallbackInterface
    ],

    # As above, idl_srcs which are not correctly positioned under a java root
    # must have idl_import_root set. Otherwise, OtherInterface (or any other
    # interface in a library which depends on this one) will not be able
    # to find CallbackInterface when it is imported.
    idl_import_root = "src",
)

# MyParcelable.aidl is imported by MyInterface.aidl, so the generated
# MyInterface.java requires MyParcelable.class at compile time.
# Depending on :parcelable ensures that aidl compilation of MyInterface.aidl
# specifies the correct import roots and can access MyParcelable.aidl, and
# makes MyParcelable.class available to Java compilation of MyInterface.java
# as usual.
android_library(
    name = "idl",
    idl_srcs = ["MyInterface.aidl"],
    deps = [":parcelable"],
)

# Here, ServiceParcelable uses and thus depends on ParcelableService,
# when it's compiled, but ParcelableService also uses ServiceParcelable,
# which creates a circular dependency.
# As a result, these files must be compiled together, in the same android_library.
android_library(
    name = "circular_dependencies",
    srcs = ["ServiceParcelable.java"],
    idl_srcs = ["ParcelableService.aidl"],
    idl_parcelables = ["ServiceParcelable.aidl"],
)

Arguments

Attributes
name

Name; required

A unique name for this target.

proguard_specs

List of labels; optional

Files to be used as Proguard specification. These will describe the set of specifications to be used by Proguard. If specified, they will be added to any android_binary target depending on this library. The files included here must only have idempotent rules, namely -dontnote, -dontwarn, assumenosideeffects, and rules that start with -keep. Other options can only appear in android_binary's proguard_specs, to ensure non-tautological merges.

android_local_test

android_local_test(name, deps, srcs, data, args, compatible_with, deprecation, exec_compatible_with, exec_properties, features, flaky, javacopts, jvm_flags, licenses, local, plugins, resource_jars, resource_strip_prefix, restricted_to, runtime_deps, shard_count, size, stamp, tags, testonly, timeout, toolchains, visibility)

This rule is for unit testing android_library rules locally (as opposed to on a device). It works with the Android Robolectric testing framework. See the Android Robolectric site for details about writing Robolectric tests.

Implicit output targets

  • name.jar: A Java archive of the test.
  • name-src.jar: An archive containing the sources ("source jar").
  • name_deploy.jar: A Java deploy archive suitable for deployment (only built if explicitly requested).

Examples

To use Robolectric with android_local_test, add Robolectric's repository to your WORKSPACE file:

http_archive(
    name = "robolectric",
    urls = ["https://github.com/robolectric/robolectric/archive/<COMMIT>.tar.gz"],
    strip_prefix = "robolectric-<COMMIT>",
    sha256 = "<HASH>",
)
load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories")
robolectric_repositories()
This pulls in the maven_jar rules needed for Robolectric. Then each android_local_test rule should depend on @robolectric//bazel:robolectric. See example below.

android_local_test(
    name = "SampleTest",
    srcs = [
        "SampleTest.java",
    ],
    manifest = "LibManifest.xml",
    deps = [
        ":sample_test_lib",
        "@robolectric//bazel:robolectric",
    ],
)

android_library(
    name = "sample_test_lib",
    srcs = [
         "Lib.java",
    ],
    resource_files = glob(["res/**"]),
    manifest = "AndroidManifest.xml",
)

Arguments

Attributes
name

Name; required

A unique name for this target.

deps

List of labels; optional

The list of other libraries to be linked in to the target. See general comments about deps at Attributes common to all build rules .
srcs

List of labels; optional

The list of source files that are processed to create the target. This attribute is almost always required; see exceptions below.

Source files of type .java are compiled. In case of generated .java files it is generally advisable to put the generating rule's name here instead of the name of the file itself. This not only improves readability but makes the rule more resilient to future changes: if the generating rule generates different files in the future, you only need to fix one place: the outs of the generating rule. You should not list the generating rule in deps because it is a no-op.

Source files of type .srcjar are unpacked and compiled. (This is useful if you need to generate a set of .java files with a genrule.)

Rules: if the rule (typically genrule or filegroup) generates any of the files listed above, they will be used the same way as described for source files.

This argument is almost always required, except if a main_class attribute specifies a class on the runtime classpath or you specify the runtime_deps argument.

javacopts

List of strings; optional

Extra compiler options for this library. Subject to "Make variable" substitution and Bourne shell tokenization.

These compiler options are passed to javac after the global compiler options.

jvm_flags

List of strings; optional

A list of flags to embed in the wrapper script generated for running this binary. Subject to $(location) and "Make variable" substitution, and Bourne shell tokenization.

The wrapper script for a Java binary includes a CLASSPATH definition (to find all the dependent jars) and invokes the right Java interpreter. The command line generated by the wrapper script includes the name of the main class followed by a "$@" so you can pass along other arguments after the classname. However, arguments intended for parsing by the JVM must be specified before the classname on the command line. The contents of jvm_flags are added to the wrapper script before the classname is listed.

Note that this attribute has no effect on *_deploy.jar outputs.

plugins

List of labels; optional

Java compiler plugins to run at compile-time. Every java_plugin specified in this attribute will be run whenever this rule is built. A library may also inherit plugins from dependencies that use exported_plugins. Resources generated by the plugin will be included in the resulting jar of this rule.
resource_jars

List of labels; optional

Set of archives containing Java resources.

If specified, the contents of these jars are merged into the output jar.

resource_strip_prefix

String; optional

The path prefix to strip from Java resources.

If specified, this path prefix is stripped from every file in the resources attribute. It is an error for a resource file not to be under this directory. If not specified (the default), the path of resource file is determined according to the same logic as the Java package of source files. For example, a source file at stuff/java/foo/bar/a.txt will be located at foo/bar/a.txt.

runtime_deps

List of labels; optional

Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will appear on the runtime classpath, but unlike them, not on the compile-time classpath. Dependencies needed only at runtime should be listed here. Dependency-analysis tools should ignore targets that appear in both runtime_deps and deps.
stamp

Integer; optional; default is 0

Enable link stamping. Whether to encode build information into the binary. Possible values:
  • stamp = 1: Stamp the build information into the binary. Stamped binaries are only rebuilt when their dependencies change. Use this if there are tests that depend on the build information.
  • stamp = 0: Always replace build information by constant values. This gives good build result caching.
  • stamp = -1: Embedding of build information is controlled by the --[no]stamp flag.

android_ndk_repository

android_ndk_repository(name, api_level, path)

Configures Bazel to use an Android NDK to support building Android targets with native code. NDK versions 10 up to 16 are currently supported.

Note that building for Android also requires an android_sdk_repository rule in your WORKSPACE file.

For more information, read the full documentation on using Android NDK with Bazel.

Examples

android_ndk_repository(
    name = "androidndk",
)

The above example will locate your Android NDK from $ANDROID_NDK_HOME and detect the highest API level that it supports.

android_ndk_repository(
    name = "androidndk",
    path = "./android-ndk-r12b",
    api_level = 24,
)

The above example will use the Android NDK located inside your workspace in ./android-ndk-r12b. It will use the API level 24 libraries when compiling your JNI code.

cpufeatures

The Android NDK contains the cpufeatures library which can be used to detect a device's CPU at runtime. The following example demonstrates how to use cpufeatures with Bazel.

# jni.cc
#include "ndk/sources/android/cpufeatures/cpu-features.h"
...
# BUILD
cc_library(
    name = "jni",
    srcs = ["jni.cc"],
    deps = ["@androidndk//:cpufeatures"],
)

Arguments

Attributes
name

Name; required

A unique name for this target.

api_level

Integer; optional; nonconfigurable; default is 0

The Android API level to build against. If not specified, the highest API level installed will be used.
path

String; optional; nonconfigurable

An absolute or relative path to an Android NDK. Either this attribute or the $ANDROID_NDK_HOME environment variable must be set.

The Android NDK can be downloaded from the Android developer site .

android_sdk_repository

android_sdk_repository(name, api_level, build_tools_version, path)

Configures Bazel to use a local Android SDK to support building Android targets.

Examples

The minimum to set up an Android SDK for Bazel is to put an android_sdk_repository rule named "androidsdk" in your WORKSPACE file and set the $ANDROID_HOME environment variable to the path of your Android SDK. Bazel will use the highest Android API level and build tools version installed in the Android SDK by default.
android_sdk_repository(
    name = "androidsdk",
)

To ensure reproducible builds, the path, api_level and build_tools_version attributes can be set to specific values. The build will fail if the Android SDK does not have the specified API level or build tools version installed.

android_sdk_repository(
    name = "androidsdk",
    path = "./sdk",
    api_level = 19,
    build_tools_version = "25.0.0",
)

The above example also demonstrates using a workspace-relative path to the Android SDK. This is useful if the Android SDK is part of your Bazel workspace (e.g. if it is checked into version control).

Support Libraries

The Support Libraries are available in the Android SDK Manager as "Android Support Repository". This is a versioned set of common Android libraries, such as the Support and AppCompat libraries, that is packaged as a local Maven repository. android_sdk_repository generates Bazel targets for each of these libraries that can be used in the dependencies of android_binary and android_library targets.

The names of the generated targets are derived from the Maven coordinates of the libraries in the Android Support Repository, formatted as @androidsdk//${group}:${artifact}-${version}. The following example shows how an android_library can depend on version 25.0.0 of the v7 appcompat library.

android_library(
    name = "lib",
    srcs = glob(["*.java"]),
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
    deps = ["@androidsdk//com.android.support:appcompat-v7-25.0.0"],
)

Arguments

Attributes
name

Name; required

A unique name for this target.

api_level

Integer; optional; nonconfigurable; default is 0

The Android API level to build against by default. If not specified, the highest API level installed will be used.

The API level used for a given build can be overridden by the android_sdk flag. android_sdk_repository creates an android_sdk target for each API level installed in the SDK with name @androidsdk//:sdk-${level}, whether or not this attribute is specified. For example, to build against a non-default API level: bazel build --android_sdk=@androidsdk//:sdk-19 //java/com/example:app.

To view all android_sdk targets generated by android_sdk_repository , you can run bazel query "kind(android_sdk, @androidsdk//...)".

build_tools_version

String; optional; nonconfigurable

The version of the Android build tools to use from within the Android SDK. If not specified, the latest build tools version installed will be used.

Bazel requires build tools version 26.0.1 or later.

path

String; optional; nonconfigurable

An absolute or relative path to an Android SDK. Either this attribute or the $ANDROID_HOME environment variable must be set.

The Android SDK can be downloaded from the Android developer site.