From 605df9bdbf6dd5219e7ba26db7ae8d1a6caf24d6 Mon Sep 17 00:00:00 2001 From: Robert Helewka Date: Sun, 21 Jun 2026 22:53:07 -0400 Subject: [PATCH] =?UTF-8?q?build:=20target=20amd64=20=E2=80=94=20Google=20?= =?UTF-8?q?ships=20no=20arm64=20Linux=20build-tools?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image pinned build-tools 36.0.0, whose aapt2/d8 are x86_64-only (Google publishes no arm64 Linux build-tools). Built for and run on arm64, packaging died with `aapt2: Syntax error: newline unexpected` (an x86_64 binary the kernel can't exec). Build the image for linux/amd64 on an amd64 runner, and point the template + README at ubuntu-24.04. The APK output is architecture-neutral, so this costs nothing downstream. Also execute aapt2 in the image sanity check so an arch mismatch fails the image build, not every app build. Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/builder-image.yml | 8 +++++--- Dockerfile | 16 ++++++++++------ README.md | 21 +++++++++++++-------- templates/build.yml | 4 +++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/builder-image.yml b/.gitea/workflows/builder-image.yml index d72a3d7..ef29570 100644 --- a/.gitea/workflows/builder-image.yml +++ b/.gitea/workflows/builder-image.yml @@ -15,7 +15,9 @@ env: jobs: build-image: - runs-on: ubuntu-24.04-arm64 + # amd64: Google ships the Linux build-tools (aapt2, d8) for x86_64 only, + # so the toolchain must be built for and run on amd64. + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 @@ -43,12 +45,12 @@ jobs: - name: Set up Buildx uses: docker/setup-buildx-action@v3 - - name: Build and push (linux/arm64) + - name: Build and push (linux/amd64) uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile - platforms: linux/arm64 + platforms: linux/amd64 push: true tags: ${{ steps.tags.outputs.tags }} # Bump these here if you want to override the Dockerfile defaults diff --git a/Dockerfile b/Dockerfile index bfa0a69..4c81adf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,9 @@ -# Native linux/arm64 Android build toolchain for CI. +# Native linux/amd64 Android build toolchain for CI. # Builds release artifacts only — no emulator, no test/system images. -# eclipse-temurin publishes a native linux/arm64 manifest, so this runs -# without emulation on an OCI Ampere (aarch64) runner. +# Must be amd64: Google publishes the Linux build-tools (aapt2, d8, …) for +# x86_64 only — there is no arm64 Linux build-tools package — so packaging +# cannot run natively on an aarch64 runner. The APK output is architecture- +# neutral regardless of the build host. FROM eclipse-temurin:21-jdk-noble # --- Version pins (bump deliberately; this is what your app repos trust) --- @@ -40,9 +42,8 @@ RUN mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools && \ ENV PATH=${PATH}:${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin:${ANDROID_SDK_ROOT}/platform-tools # Accept licenses and bake the SDK packages into the image so prod builds -# don't depend on Google's endpoint at job time. -# aapt2 and the build-tools binaries ship native arm64 for 35.x, so APK/AAB -# packaging runs natively on aarch64. +# don't depend on Google's endpoint at job time. The build-tools binaries +# (aapt2, d8) are x86_64 ELF — this is why the image must be amd64. RUN yes | sdkmanager --licenses >/dev/null && \ sdkmanager --install \ "platform-tools" \ @@ -51,7 +52,10 @@ RUN yes | sdkmanager --licenses >/dev/null && \ rm -rf ${ANDROID_SDK_ROOT}/.android # Sanity: fail the image build if the toolchain isn't actually usable. +# Execute aapt2 (not just --version a tool) so an arch mismatch in the +# build-tools binaries fails the image build here, not in every app build. RUN java -version && sdkmanager --version && node --version && \ + "${ANDROID_SDK_ROOT}/build-tools/${BUILD_TOOLS_VERSION}/aapt2" version && \ test -d "${ANDROID_SDK_ROOT}/platforms/${PLATFORM_VERSION}" WORKDIR /workspace \ No newline at end of file diff --git a/README.md b/README.md index 29e1af2..316f3a8 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,23 @@ # android-builder -Native `linux/arm64` Android build toolchain for CI, published to the Gitea +Native `linux/amd64` Android build toolchain for CI, published to the Gitea container registry at `git.helu.ca/r/android`. App repos consume this image to build signed release artifacts. Instrumented tests are **not** part of this toolchain — by design, CI builds are promotions of code already tested in Dev (on Apple silicon, where the emulator runs -natively). The OCI Ampere (aarch64) runner has no `/dev/kvm` (the guest VM -boots at EL1, so KVM can't access HYP/EL2), so there's no accelerated emulator -here — and we don't need one. +natively). + +**Why amd64:** Google publishes the Linux Android build-tools (`aapt2`, `d8`, +…) for **x86_64 only** — there is no arm64 Linux build-tools package. Running +the toolchain on an aarch64 runner fails at resource packaging +(`aapt2: Syntax error: newline unexpected`, an x86_64 binary the kernel can't +exec). The produced APK/AAB is architecture-neutral regardless of build host, +so building on amd64 costs nothing on the output side. ## What's in the image -- Eclipse Temurin JDK 21 (native arm64) +- Eclipse Temurin JDK 21 (native amd64) - Android cmdline-tools, platform, and build-tools — **baked in**, so prod builds don't depend on Google's download endpoint at job time - `git`, `curl`, `unzip` @@ -27,8 +32,8 @@ Pinned versions live as `ARG`s at the top of the `Dockerfile`: | `BUILD_TOOLS_VERSION` | `36.0.0` | SDK Manager / release notes | | `PLATFORM_VERSION` | `android-36`| your app's `compileSdk` | -`aapt2` and the build-tools binaries ship native arm64 for 36.x, so packaging -runs without emulation. +The build-tools binaries (`aapt2`, `d8`) are x86_64 ELF — this is why the +image is amd64 (see "Why amd64" above). ## Tagging model @@ -63,7 +68,7 @@ app and pin the toolchain: ```yaml jobs: build: - runs-on: ubuntu-24.04-arm64 + runs-on: ubuntu-24.04 container: image: git.helu.ca/r/android:2026.06 credentials: diff --git a/templates/build.yml b/templates/build.yml index 5d9a208..052c122 100644 --- a/templates/build.yml +++ b/templates/build.yml @@ -24,7 +24,9 @@ env: jobs: build: - runs-on: ubuntu-24.04-arm64 + # amd64: the toolchain image carries x86_64 Android build-tools (Google + # ships no arm64 Linux build-tools), so run it on an amd64 runner. + runs-on: ubuntu-24.04 container: image: git.helu.ca/r/android:2026.06 credentials: