/bazel_android_sdk_downloader

Drop-in replacement for the Bazel build system's Android repository rules to automate the downloading and installation of the Android SDK

Primary LanguagePythonApache License 2.0Apache-2.0

Android SDK Downloader for Bazel Build Status

This package is to aid development of Android applications via Bazel. Without it, the setup instructions for building Android with Bazel involve manually downloading and installing the Android SDK. My understanding is that this is because you cannot download the SDK without accepting the licenses, which may not be okay to automate. Why not automate everything but the license agreement?

This project aims to serve as a drop-in replacement for native android repository rules.

How to use

WORKSPACE file changes

In your WORKSPACE file, replace the following block

android_sdk_repository(
    name = "androidsdk",
    path = "../path/to/sdk",
    api_level = 27,
    build_tools_version = "27.0.3",
)

with this instead

git_repository(
    name = "android_sdk_downloader",
    remote = "https://github.com/quittle/bazel_android_sdk_downloader",
    commit = "<HEAD-COMMIT>",
)

load("@android_sdk_downloader//:rules.bzl", "android_sdk_repository")

android_sdk_repository(
    name = "androidsdk",
    workspace_name = "<YOUR-WORKSPACE-NAME>",
    api_level = 27,
    build_tools_version = "27.0.3",
)

One-time install step

Then run

bazel run @androidsdk//install

This will attempt to download the SDK for the versions specified. If you change these values, clean the workspace, or check it out fresh, you will need to re-run this command to download and install the SDK again.

Profit

You should now be able to run your build as normal.

bazel build ...

Continuous Integration

In a Contuous Integration (CI) environment, you need a way of programmatically accepting the licenses. The easiest way on unix-like systems is to pipe yes into the install command as part of your install or build step.

yes | bazel run @androidsdk//install

Troubleshooting

My build fails with this cryptic error

no such package '@android_sdk_repository_androidsdk//': /home/ubuntu/workspace/my_project/bazel-bin/external/androidsdk/install/sdk.runfiles/my_project/_ (No such file or directory) and referenced by '//external:android/sdk'

or

ERROR: missing input file '@android_sdk_repository_androidsdk//:build-tools/26.0.1/lib/apksigner.jar'
ERROR: /home/ubuntu/workspace/my_project/BUILD:1:1: //:test_binary: missing input file '@android_sdk_repository_androidsdk//:build-tools/26.0.1/lib/apksigner.jar'

or

ERROR: /home/ubuntu/workspace/my_project/rules.bzl:88:5: no such package '@android_sdk_repository_androidsdk//': Android SDK api level 25 was requested but it is not installed in the Android SDK at /home/ubuntu/workspace/my_project/bazel-bin/external/androidsdk/install/sdk.runfiles/my_project/_. The api levels found were [26]. Please choose an available api level or install api level 25 from the Android SDK Manager. and referenced by '//external:android/sdk'

The first error message is for a clean workspace before you have run the install step. The second occurs when you updated the build_tools_version but for got to run install again. The third happens when you updated the api_level but forgot run install again. Basically, try re-running the installation step before getting too concerned. There is no need to clean between changes.

My build fails with Skipping following packages as the license is not accepted

This will occur when running the install step but you are unable to actually type y to accept the licence. This occurs on Bazel versions prior to 0.14.0. Prior to this, you must pass --direct_run as a Bazel flag when running the install command. e.g.

bazel run @androidsdk//install --direct_run

Notes

Why is the workspace_name a parameter of the rule?

It is not too intrusive for now but would like to find a way to remove this requirement.

Why do I need --direct_run with Bazel prior to 0.14.0

Prior to this version, the default behavior of Bazel was to not run interactively so you needed to pass this flag in order for it to listen for y to accept the licenses. This flag no longer needed when running with Bazel 0.14.0 or later as this is now the default mode.