Skip to content

ci(sdk_v2): build the C++ core for Android in the native pipeline - #954

Draft
sheetalarkadam wants to merge 1 commit into
fix/genai-aar-cache-stalenessfrom
ci/android-native-build
Draft

ci(sdk_v2): build the C++ core for Android in the native pipeline#954
sheetalarkadam wants to merge 1 commit into
fix/genai-aar-cache-stalenessfrom
ci/android-native-build

Conversation

@sheetalarkadam

Copy link
Copy Markdown

What

Adds two cross-compiled Android stages — arm64-v8a and x86_64 — to the sdk_v2 native build graph, plus a reusable steps-build-android.yml template. Both run on the existing Linux pool (onnxruntime-Ubuntu2404-AMD-CPU) via the NDK, so no new pool is needed.

Why

Android resolves its native dependencies from different origins than the desktop platforms:

Dependency Desktop Android
ORT Microsoft.ML.OnnxRuntime NuGet same NuGet, runtimes/android-{arm64,x64}
GenAI Microsoft.ML.OnnxRuntimeGenAI.Foundry NuGet standalone AAR on GitHub Releases

Because GenAI comes from a different origin, a version that exists on NuGet does not necessarily exist as an Android AAR — and today nothing in CI notices.

That is not hypothetical. main is currently in exactly that state:

$ grep onnxruntime-genai sdk_v2/deps_versions.json
"onnxruntime-genai": { "version": "0.15.1" }

$ curl -sI https://github.com/microsoft/onnxruntime-genai/releases/download/v0.15.1/onnxruntime-genai-android-0.15.1.aar
HTTP/2 404

$ curl -sI https://github.com/microsoft/onnxruntime-genai/releases/download/v0.15.0/onnxruntime-genai-android-0.15.0.aar
HTTP/2 200      # 20.6 MB

A clean Android configure against main fails hard:

CMake Error at cmake/FindOnnxRuntimeGenAI.cmake:137 (message):
  Failed to download GenAI AAR: "HTTP response code said error"

v0.15.1 exists on NuGet but has no GitHub release, so every desktop leg is green while Android cannot configure at all. That has been true since 6f35431 ("Update ort and ort-genai package (#934)").

So this PR is expected to fail its own new Android stages on first run. That red is the point — it is the bug the stages exist to catch. Repinning is intentionally left out of this PR; see below.

Scope / decisions

  • Build-only. Emulator tests are plumbed behind a runEmulatorTests parameter on the x86_64 leg (the only ABI build.py --android_run_emulator supports) but default to off. This stage is here to guard the build and the dependency wiring; an emulator boot adds runtime and flakiness that should be opted into once the leg is proven stable.
  • Not wired into the pack stages. The stages publish cpp-native-android-<abi> artifacts, but neither the NuGet package nor the C++ SDK tgz has an Android consumer today, and Android's differing dependency origins make packaging a separate design question.
  • All three .so files are staged, unlike the desktop legs which stage only libfoundry_local.so. Desktop consumers get ORT/GenAI out of band (pip on the Python side, NuGet on the C# side); an Android consumer has no such channel, so the libraries must be captured alongside libfoundry_local.so.
  • NDK is pinned (29.0.14206865) and resolved from the pool image where present, falling back to sdkmanager only if absent — so a pool image refresh cannot silently change the toolchain.

Follow-ups (not in this PR)

  1. Repin GenAI to a version with an Android AAR (0.15.0 is the newest, and the closest pairing to ORT 1.28.0) — or get 0.15.1 published for Android. This touches both sdk_v2/deps_versions.json and the matching literal in .pipelines/foundry-local-packaging.yml, and it changes the desktop dependency too, so it deserves its own PR and the judgement of whoever landed Update ort and ort-genai package #934.
  2. The stale-cache mask in FindOnnxRuntimeGenAI.cmake. The AAR download is guarded on _deps/genai-android-aar already existing (L128–L130), and the extraction directory is not keyed on the version. A local tree with a warm build dir therefore keeps linking whatever AAR it downloaded first while CMake cheerfully logs the resolved version — I hit this locally, building against a 0.14.0 AAR while the log said 0.15.1. Keying the directory on ${ORT_GENAI_VERSION} would fix it. CI is immune (always a fresh binary dir), which is arguably why this survived; it is the nastier of the two bugs for developers.

Testing

Both ABIs build green locally with GenAI repinned to a version that has an AAR:

build/Android-arm64-v8a/Release/bin/  libfoundry_local.so  libonnxruntime.so  libonnxruntime-genai.so
build/Android-x86_64/Release/bin/     libfoundry_local.so  libonnxruntime.so  libonnxruntime-genai.so

YAML validated locally; stage graph resolves to:

cpp_build_win_x64, cpp_build_win_arm64, cpp_build_linux_x64, cpp_build_linux_arm64,
cpp_build_osx_arm64, cpp_build_android_arm64, cpp_build_android_x86_64,
cpp_pack_sdk_v2, cpp_pack_nuget

Draft because the new stages have not yet run on a real agent — the NDK-resolution step in particular needs to be confirmed against the actual pool image.

@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
foundry-local Ready Ready Preview Aug 7, 2026 12:22am

Request Review

Adds two cross-compiled Android stages (arm64-v8a, x86_64) to the sdk_v2
native build graph, running on the existing Linux pool via the NDK.

Android resolves its native dependencies from different origins than the
desktop platforms: ORT comes from the same Microsoft.ML.OnnxRuntime NuGet
package, but GenAI ships as a standalone AAR on GitHub Releases. A version
that exists on NuGet therefore does not necessarily exist for Android, and
today nothing in CI notices - every desktop leg goes green while the Android
build cannot configure at all.

The stages publish `cpp-native-android-<abi>` artifacts but are deliberately
not wired into either pack stage; neither the NuGet package nor the C++ SDK
tgz has an Android consumer yet, so packaging is left as a separate question.

Build-only for now. Emulator tests are plumbed behind a `runEmulatorTests`
parameter on the x86_64 leg and can be enabled once the leg is proven stable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 24ef037b-246f-4fea-a1a3-4fae5223cb0c
@sheetalarkadam
sheetalarkadam force-pushed the ci/android-native-build branch from b72f5e3 to d859c00 Compare August 7, 2026 00:21
@sheetalarkadam
sheetalarkadam changed the base branch from fix/genai-android-nuget to fix/genai-aar-cache-staleness August 7, 2026 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant