┌─────────────────────────────────────────────────────────────┐ │ android-arm-build-tools v36.1.0 │ └─────────────────────────────────────────────────────────────┘
$ android-arm-build-tools
drop-in aapt2, aidl, zipalign,
split-select for Linux ARM64.
why does this exist
Google's sdkmanager ships these four binaries for
linux-x86_64 only. On a Raspberry Pi, Asahi Linux box,
ARM Chromebook, Ampere server, or native-arm64 WSL, the Android
Gradle Plugin invokes them and gets exec format error
instead of an APK.
This project bypasses Soong, clones ~40 specific AOSP repos, and
cross-compiles the four binaries against glibc with
gcc-aarch64-linux-gnu. Result: drop in, build APKs
natively on arm64.
install
Install the matching build-tools first via sdkmanager —
the Java pieces (apksigner, dx, etc.) come
from there. We only replace the four native binaries.
sdkmanager "build-tools;36.1.0" Then run the installer:
curl -fsSL https://raw.githubusercontent.com/Commit451/android-arm-build-tools/main/install.sh | bash
The script picks up the latest release, detects your SDK via
$ANDROID_HOME / $ANDROID_SDK_ROOT /
~/Android/Sdk, and writes the binaries into
$SDK/build-tools/<version>/. To pin a specific
version or use a non-default SDK path:
./install.sh --version 36.1.0 --sdk /opt/android-sdk
It refuses to run on non-aarch64 hosts and on SDKs missing the
target build-tools/<version>/ directory.
agp 9.x: also point aapt2 at the arm64 binary
Android Gradle Plugin 9.x stopped using the SDK's
aapt2 and instead pulls its own from Maven
(com.android.tools.build:aapt2:<agp>:linux),
which is x86_64-only. The drop-in is still needed by other build
steps, but on AGP 9+ also add this to
gradle.properties (project- or user-level):
android.aapt2FromMavenOverride=/home/you/Android/Sdk/build-tools/36.1.0/aapt2
Restart the Gradle daemon afterward (./gradlew --stop).
AGP 8.x and older don't need this — they still shell out to the SDK's
aapt2.
available versions
Auto-refreshed when the site rebuilds. Each tag is built from the AOSP source ref shown.
| version | android | source ref | status | published | |
|---|---|---|---|---|---|
| 36.1.0 | Android 16 QPR1 | android-16.0.0_r3 | mapped | 2026-05-22 | download |
| 36.0.0 | Android 16 GA | android-16.0.0_r1 | mapped | 2026-05-22 | download |
| 35.0.1 | Android 15 | platform-tools-35.0.1 | legacy | 2026-05-21 | download |
what about 37.0.0 or whatever's newer than the latest above
sdkmanager sometimes publishes a build-tools version before AOSP
tags the corresponding source publicly. 37.0.0 is the
current example: Google ships the binary but the underlying source
hasn't appeared in any public AOSP branch we can build from. When
that changes, our daily workflow auto-detects the new tag and a
matching arm64 release lands here — no action needed on this end.
compatibility
Binaries are built on Debian 12 (Bookworm) — glibc 2.36, GCC 12 — so they need glibc 2.36+ and GLIBCXX_3.4.30+ at runtime. Distros that work out of the box:
Older distros: build from source against your distro's libc.
verify
After install, this should work in any AGP project without
exec format error:
./gradlew :app:assembleDebug Or smoke-test the binary directly:
$ANDROID_HOME/build-tools/36.1.0/aapt2 version
# Android Asset Packaging Tool (aapt) 2.X-...