Skip to content

Commit451/android-arm-build-tools

Repository files navigation

android-arm-build-tools

Drop-in aapt2, aidl, zipalign, and split-select binaries for Linux on ARM64 — the four Android SDK build-tools that Gradle/AGP actually invokes during a normal app build.

Google's sdkmanager only ships these for linux-x86_64. On a Raspberry Pi, Asahi Linux machine, ARM Chromebook, Ampere server, or native-arm64 WSL, AGP fails with exec format error until you swap in arm64 builds. This project ships those, automatically rebuilt as upstream AOSP publishes new build-tools source tags.

Install

You already need the matching build-tools installed via sdkmanager first (the Java parts — 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

That picks up the latest Release, detects your SDK via $ANDROID_HOME / $ANDROID_SDK_ROOT / ~/Android/Sdk, and drops the binaries into $SDK/build-tools/<version>/.

To pin a specific version, or use a non-default SDK path:

curl -fsSL https://raw.githubusercontent.com/Commit451/android-arm-build-tools/main/install.sh -o install.sh
chmod +x install.sh
./install.sh --version 36.0.0 --sdk /opt/android-sdk

Available versions are listed on the Releases tab. The script refuses to run on non-aarch64 hosts and on hosts that don't already have the matching 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-version>:linux), which is x86_64-only. The drop-in above is still needed by other steps, but on AGP 9+ you also have to tell Gradle to use the arm64 binary directly.

Prefer putting the override in your user-level Gradle properties file so every Android project on that ARM64 machine picks it up without committing machine-specific paths to an app repository:

mkdir -p ~/.gradle
cat >> ~/.gradle/gradle.properties <<'EOF'
android.aapt2FromMavenOverride=/home/you/Android/Sdk/build-tools/36.1.0/aapt2
EOF

Use the full path to the aapt2 that this project's installer just wrote. If you only want the override for one project, you can instead add the same property to that project's gradle.properties. Do not put it in local.properties; AGP does not read this override from there.

Restart the Gradle daemon (./gradlew --stop) after changing the property so it picks up the new binary.

If you're on AGP 8.x or older you can skip this step — those versions still shell out to $SDK/build-tools/<v>/aapt2.

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-...

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:

  • Raspberry Pi OS Bookworm (glibc 2.36) ✅
  • Debian 12+ ✅
  • Ubuntu 22.04+ ✅ (glibc 2.35 — close enough; libstdc++ matches)
  • Fedora 38+ / Asahi Linux ✅
  • Anything newer than the above ✅

If you're on something older, build from source against your distro's libc.

Available versions

We ship the versions where AOSP has tagged public source we can build from. As of writing:

  • 37.0.0 — Android 17 GA, built from android-17.0.0_r1
  • 36.1.0 — Android 16 QPR1, built from android-16.0.0_r3
  • 36.0.0 — Android 16 GA, built from android-16.0.0_r1
  • 35.0.1 — Android 15, built from platform-tools-35.0.1

AGP doesn't require build-tools to match compileSdk, so any of the above paired with e.g. compileSdk 37 works fine.

What about future versions?

sdkmanager sometimes publishes a build-tools version before AOSP tags the corresponding source publicly. During that gap, the resolver marks the version no-source and no arm64 release is published yet. 37.0.0 used to be in that state; it is now built from android-17.0.0_r1 and available on the Releases tab. When a future source tag appears, our daily workflow auto-detects it and publishes a matching arm64 build (no action needed on this end). See DEV.md for the resolver design.

Releases

All builds are on the Releases tab. A GitHub Actions workflow runs daily, resolves each sdkmanager build-tools version to an AOSP source ref (legacy platform-tools-* tag or the newer android-NN.0.0_rN scheme), and publishes a fresh release when something new shows up.

If you'd rather grab a single binary directly, each Release has aapt2, aidl, zipalign, split-select, a combined .tar.xz, and SHA256SUMS attached.

Building from source / contributing

See DEV.md.

Refs

License

MIT. See LICENSE.

\ ゜o゜)ノ