# Android build targets

Every step of an Android build, and every device action, is a build target. `elide run`, `elide test --device` and
the `android/*` agent tools run these targets, and `elide build <target>` runs any of them directly. List them, with
their options, without running anything:

```bash
elide build --inspect
elide build android-run-app --help
```

In the names below, `<a>` is an application artifact, `<l>` a library, `<b>` a bundle, `<x>` any of them, `<d>` a
device from `android.devices`, and `<t>` a test source set.

## Building

| Target | Runs | Writes |
| --- | --- | --- |
| `android-sdk` | `sdkmanager` | The lockfile's SDK record |
| `android-libraries` | — | Unpacked `.aar`s under `.dev/android/libraries/` |
| `android-resources-<x>` | `aapt2 compile` | Compiled resources |
| `android-manifest-<x>` | — | The merged `AndroidManifest.xml` |
| `android-link-<x>` | `aapt2 link` | `resources.apk` and `R.java` |
| `android-r-<x>` | `javac` | Compiled `R` classes |
| `android-dex-<a>` | `d8` | `classes*.dex` |
| `android-r8-<a>` | R8, in place of `d8` when minified | `classes*.dex`, `mapping.txt` |
| `android-mapping-<a>` | — | `.dev/artifacts/<a>-mapping.txt` |
| `android-package-<a>` | — | The unaligned APK |
| `android-align-<a>` | `zipalign -P 16` | The aligned APK |
| `android-signing-<a>` | `keytool` | The debug keystore, when it is missing |
| `android-sign-<a>` | `apksigner` | The signed APK |
| `android-classes-<l>` | — | The library's `classes.jar` |
| `android-module-<b>` | — | A bundle module zip |
| `android-bundle-<b>` | `bundletool` | The bundle, before signing |
| `<a>`, `<l>`, `<b>` | — | `.dev/artifacts/<name>.{apk,aar,aab}` |
| `<a>-androidTest` | the same pipeline | The instrumented test APK |

Resources are linked before the code compiles, which is what makes `R` usable: the `R` classes are placed on the
compile classpath of the artifact's source sets. A build that changed nothing re-runs none of it; adding a resource
re-runs the compile, the dex and the packaging. Intermediate files live under `.dev/android/<x>/`.

## Devices

None of these is a default target: `elide build` alone never touches a device.

| Target | Does |
| --- | --- |
| `android-run-<a>` | Install and launch on `--device`, the one attached device, or the project's emulator |
| `android-run-device-<a>` | The same, on a physical device only |
| `android-run-emulator-<a>` | The same, on the project's emulator, booted or reused |
| `android-debug-<a>` | Launch suspended and forward JDWP |
| `android-test-<a>` | Run instrumented tests |
| `android-test-<a>-on-<d>` | Run them on a declared test device |
| `android-test-<a>-on-all` | Run them on every declared test device |
| `android-emulator` | Boot the project's AVD and wait for it |
| `android-emulator-stop` | Stop the emulator running the project's AVD |
| `android-avd` | Create or repair the AVD without booting it |
| `android-keystore-<a>` | Create the keystore `signing` names |

Run and debug targets exist only for a signed APK, and debug targets only for a debuggable one. `android-avd`,
`android-emulator` and `android-emulator-stop` are one per project, registered when it has a signed APK.

## Host tests

Ahead of each test source set's run, one artifact is linked again with the test libraries
([Android tests](/docs/toolchain/android/testing#host-tests)):

| Target | Writes |
| --- | --- |
| `android-resources-<a>-<t>` | The artifact's and every library's resources, compiled |
| `android-manifest-<a>-<t>` | The manifest, merged with test libraries' too |
| `android-link-<a>-<t>`, `android-r-<a>-<t>` | `resources.apk` and `R` for every package |
| `android-host-test-<a>-<t>` | The resource APK, assets and the Robolectric test configuration |

## Options

| Option | Targets | Effect |
| --- | --- | --- |
| `--device=<serial>` | run, debug, test | Use that attached device. |
| `--device=<serial>` | `android-emulator-stop` | Stop that emulator. |
| `--emulator` | debug, test | Use the project's emulator, booting it if needed. |
| `--window`, `--no-window` | anything that boots an emulator | Show the window or run headless. |
| `--no-follow` | run, debug | Return once launched instead of following the log. |
| `--debug[=<port>]` | debug | The local JDWP port; a free one when bare. |
| `--tests=<class>[#<method>]` | test | Tests to run; repeatable or comma-separated. |
| `--install-sdk` | any | Install missing SDK components, accepting their licenses. |
| `--release` | `android-keystore-<a>` | Create a release keystore ([Signing and release](/docs/toolchain/android/release)). |

Options are not part of a target's cache key, except `--release`.

## Commands and their targets

| Command | Target |
| --- | --- |
| `elide run [app]` | `android-run-<app>` |
| `elide run --emulator` | `android-run-emulator-<app>` |
| `elide run --debugger[=<port>]` | `android-debug-<app> [--debug=<port>]` |
| `elide test --device[=<serial>]` | `android-test-<app> [--device=<serial>]` |
| `elide test --device=<d>` | `android-test-<app>-on-<d>` |
| `elide test --device=all` | `android-test-<app>-on-all` |
| `elide install` | `android-sdk`, installing; then `android-libraries` and `android-r-<x>` for the editor classpath |
| `elide build --release` | Every application, as a release build ([Signing and release](/docs/toolchain/android/release#release-builds)) |
