Skip to content
Nix Android build tests
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
androidenv
tests
.gitignore
LICENSE
README.md

README.md

Android build environment for Nix

This repository contains facilities to deploy the Android SDK and its plugins, build Android projects and spawn emulator instances, by using the Nix package manager.

You probably do not want to use the stuff in this repository directly -- the functionality provided by this package also exists in the upstream version of Nixpkgs.

This repository is a standalone version for experimentation/testing purposes. All changes in this repository are supposed to (eventually) land in the upstream Nixpkgs repository.

Prerequisites

Usage

The Android build environment provides three major features and a number of supporting features.

Deploying an Android SDK installation with plugins

The first use case is deploying the SDK with a desired set of plugins or subsets of an SDK.

let
  androidenv = import ./androidenv {};

  androidComposition = androidenv.composeAndroidPackages {
    toolsVersion = "25.2.5";
    platformToolsVersion = "27.0.1";
    buildToolsVersions = [ "27.0.3" ];
    includeEmulator = false;
    emulatorVersion = "27.2.0";
    platformVersions = [ "24" ];
    includeSources = false;
    includeDocs = false;
    includeSystemImages = false;
    systemImageTypes = [ "default" ];
    abiVersions = [ "armeabi-v7a" ];
    lldbVersions = [ "2.0.2558144" ];
    cmakeVersions = [ "3.6.4111459" ];
    includeNDK = false;
    ndkVersion = "16.1.4479499";
    useGoogleAPIs = false;
    useGoogleTVAddOns = false;
    includeExtras = [
      "extras;google;gcm"
    ];
  };
in
androidComposition.androidsdk

The above function invocation states that we want an Android SDK with the above specified plugin versions. By default, most plugins are disabled. Notable exceptions are the tools, platform-tools and build-tools sub packages.

The following parameters are supported:

  • toolsVersion, specifies the version of the tools package to use
  • platformsToolsVersion specifies the version of the platform-tools plugin
  • buildToolsVersion specifies the versions of the build-tools plugins to use.
  • includeEmulator specifies whether to deploy the emulator package (false by default). When enabled, the version of the emulator to deploy can be specified by setting the emulatorVersion parameter.
  • includeDocs specifies whether the documentation catalog should be included.
  • lldbVersions specifies what LLDB versions should be deployed.
  • cmakeVersions specifies which CMake versions should be deployed.
  • includeNDK specifies that the Android NDK bundle should be included. Defaults to: false.
  • ndkVersion specifies the NDK version that we want to use.
  • includeExtras is an array of identifier strings referring to arbitrary add-on packages that should be installed.
  • platformVersions specifies which platform SDK versions should be included.

For each platform version that has been specified, we can apply the following options:

  • includeSystemImages specifies whether a system image for each platform SDK should be included.
  • includeSources specifies whether the sources for each SDK version should be included.
  • useGoogleAPIs specifies that for each selected platform version the Google API should be included.
  • useGoogleTVAddOns specifies that for each selected platform version the Google TV add-on should be included.

For each requested system image we can specify the following options:

  • systemImageTypes specifies what kind of system images should be included. Defaults to: default.
  • abiVersions specifies what kind of ABI version of each system image should be included. Defaults to: armeabi-v7a.

Most of the function arguments have reasonable default settings.

When building the above expression with:

$ nix-build

The Android SDK gets deployed with all desired plugin versions.

We can also deploy subsets of the Android SDK. For example, to only the the platform-tools package, you can evaluate the following expression:

let
  androidenv = import ./androidenv {};

  androidComposition = androidenv.composeAndroidPackages {
    # ...
  };
in
androidComposition.platform-tools

Using predefined Android package compositions

In addition to composing an Android package set manually, it is also possible to use a predefined composition that contains all basic packages for a specific Android version, such as version 9.0 (API-level 28).

The following Nix expression can be used to deploy the entire SDK with all basic plugins:

let
  androidenv = import ./androidenv {};
in
androidenv.androidPkgs_9_0.androidsdk

It is also possible to use one plugin only:

{androidenv}:

androidenv.androidPkgs_9_0.platform-tools

Building an Android application

In addition to the SDK, it is also possible to build an Ant-based Android project and automatically deploy all the Android plugins that a project requires.

let
  androidenv = import ./androidenv {};
in
androidenv.buildApp {
  name = "MyAndroidApp";
  src = ./myappsources;
  release = true;

  # If release is set to true, you need to specify the following parameters
  keyStore = ./keystore;
  keyAlias = "myfirstapp";
  keyStorePassword = "mykeystore";
  keyAliasPassword = "myfirstapp";

  # Any Android SDK parameters that install all the relevant plugins that a
  # build requires
  platformVersions = [ "24" ];

  # When we include the NDK, then ndk-build is invoked before Ant gets invoked
  includeNDK = true;
}

Aside from the app-specific build parameters (name, src, release and keystore parameters), the buildApp {} function supports all the function parameters that the SDK composition function (the function shown in the previous section) supports.

This build function is particularly useful when it is desired to use Hydra: the Nix-based continuous integration solution to build Android apps. An Android APK gets exposed as a build product and can be installed on any Android device with a web browser by navigating to the build result page.

Spawning emulator instances

For testing purposes, it can also be quite convenient to automatically generate scripts that spawn emulator instances with all desired configuration settings.

An emulator spawn script can be configured by invoking the emulateApp {} function:

let
  androidenv = import ./androidenv {};
in
androidenv.emulateApp {
  name = "emulate-MyAndroidApp";
  platformVersion = "24";
  abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
  systemImageType = "default";
  useGoogleAPIs = false;
}

It is also possible to specify an APK to deploy inside the emulator and the package and activity names to launch it:

let
  androidenv = import ./androidenv {};
in
androidenv.emulateApp {
  name = "emulate-MyAndroidApp";
  platformVersion = "24";
  abiVersion = "armeabi-v7a"; # mips, x86 or x86_64
  systemImageType = "default";
  useGoogleAPIs = false;
  app = ./MyApp.apk;
  package = "MyApp";
  activity = "MainActivity";
}

In addition to prebuilt APKs, you can also bind the APK parameter to a buildApp {} function invocation shown in the previous example.

Querying the available versions of each plugin

When using any of the previously shown functions, it may be a bit inconvenient to find out what options are supported, since the Android SDK provides many plugins.

A shell script in the androidenv/ sub directory can be used to retrieve all possible options:

sh ./querypackages.sh packages build-tools

The above command-line instruction queries all build-tools versions in the generated packages.nix expression.

Updating the generated expressions

Most of the Nix expressions are generated from XML files that the Android package manager uses. To update the expressions run the generate.sh script that is stored in the androidenv/ sub directory:

sh ./generate.sh

Test cases

The tests/ sub folder contains a collection of testcases that can be used to validate the Android build functionality.

License

The contents of this package (except for the Android example project) is covered by the same license as Nixpkgs -- the MIT license.

You can’t perform that action at this time.