Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

aapt2-qemu

Run Android's aapt2 (x86-64) on aarch64 Linux via QEMU user mode.

Google ships aapt2 only as an x86-64 binary. On ARM64 Linux (Apple Silicon Asahi, Raspberry Pi 5, etc.) AGP runs it through the system's binfmt_misc dispatcher, which can be unreliable. This project wraps it with qemu-x86_64 for consistent behaviour and predictable performance (~0.07 s per call).

Prerequisites

sudo dnf install -y qemu-user erofs-utils

Debian/Ubuntu: sudo apt install qemu-user-static erofs-utils
Arch: sudo pacman -S qemu-user-static erofs-utils

Usage

Please read the script before executing it. For safety concerns, always do so.

curl -sLO https://raw.githubusercontent.com/IgnacioLD/aapt2-qemu/main/aapt2-qemu-setup.sh
# review the script:
less aapt2-qemu-setup.sh
# run it:
sh aapt2-qemu-setup.sh
./gradlew assembleDebug

The script:

  1. Mounts the FEX emulator rootfs (erofs image) as the x86-64 sysroot.
  2. Locates the newest x86-64 aapt2 that AGP already downloaded.
  3. Writes a tiny wrapper that invokes qemu-x86_64 -L <sysroot> <aapt2>.
  4. Sets android.aapt2FromMavenOverride in ~/.gradle/gradle.properties.

Run it once per session — the FUSE mount is ephemeral.

Environment

Variable Default Description
AAPT2_EROFS /usr/share/fex-emu/RootFS/default.erofs Path to the FEX rootfs image
AAPT2_SYSROOT /tmp/aapt2-x86root Mount point for the FUSE image
AAPT2_WRAPPER_DIR $HOME/.local/share/aapt2-qemu Where the wrapper script lives

Override any of them to customise paths:

AAPT2_SYSROOT=/custom/mount ./aapt2-qemu-setup.sh

Without FEX

If you don't have FEX installed, provide any x86-64 rootfs that contains lib64/ld-linux-x86-64.so.2 and the required libraries. Set AAPT2_EROFS to a directory instead of an erofs image (the script skips the FUSE mount when it's not a file).

AAPT2_EROFS=/custom-x86-rootfs ./aapt2-qemu-setup.sh

How the wrapper works

AGP calls aapt2 during resource processing. The wrapper:

  • For aapt2 version: merges stderr→stdout because aapt2 prints its version banner to stderr but AGP reads the version from stdout.
  • For all other commands: passes everything through to qemu-x86_64 without redirecting stderr (AGP monitors the daemon's stderr pipe and treats EOF as a crash).

The wrapper filename must end in aapt2 — AGP checks this with path.endsWith("aapt2") and rejects anything else.

adb

The SDK adb at $ANDROID_HOME/platform-tools/adb is also x86-64 and won't run natively. Install the native ARM64 package instead:

sudo dnf install android-tools

Then use /usr/bin/adb (or ensure it comes first in $PATH).

Debian/Ubuntu: sudo apt install adb
Arch: sudo pacman -S android-tools

License

MIT

About

Run AGP x86-64 aapt2 on aarch64 via qemu-user

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages