ci(sdk_v2): build the C++ core for Android in the native pipeline - #954
Draft
sheetalarkadam wants to merge 5 commits into
Draft
ci(sdk_v2): build the C++ core for Android in the native pipeline#954sheetalarkadam wants to merge 5 commits into
sheetalarkadam wants to merge 5 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
sheetalarkadam
force-pushed
the
ci/android-native-build
branch
from
August 6, 2026 23:58
16cfb94 to
b72f5e3
Compare
sheetalarkadam
force-pushed
the
ci/android-native-build
branch
from
August 7, 2026 00:21
b72f5e3 to
d859c00
Compare
sheetalarkadam
changed the base branch from
fix/genai-android-nuget
to
fix/genai-aar-cache-staleness
August 7, 2026 00:22
sheetalarkadam
force-pushed
the
ci/android-native-build
branch
from
August 7, 2026 20:52
a48a5d7 to
491e1c2
Compare
sheetalarkadam
force-pushed
the
ci/android-native-build
branch
from
August 10, 2026 18:04
491e1c2 to
e148a44
Compare
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
The Android staging step copied three .so files and its comment claimed that was all of them. GenAI 0.15.0 split most of libonnxruntime-genai.so into libmat.so and records it as a DT_NEEDED, so the published artifact was missing a library its own contents require -- a consuming APK would build green and then fail to dlopen at runtime. Stage libmat.so, guarded on existence to mirror the copy in sdk_v2/cpp/CMakeLists.txt so 0.14.x keeps working unchanged. To stop this class of bug returning, assert DT_NEEDED closure over the staged set. The check keys off "the build produced this library in bin/", so system libraries are excluded without a whitelist and it cannot fail spuriously on an agent whose image differs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24ef037b-246f-4fea-a1a3-4fae5223cb0c
Every other native producer stage uses the same arch token in its stage id and its artifact name (cpp_build_linux_arm64 -> cpp-native-linux-arm64). The Android arm64 stage shortened the ABI to "arm64" while publishing cpp-native-arm64-v8a, and did not even agree with its own x86_64 sibling, which already carries the full ABI string. Renaming is free right now because the stage has never run on main, so no branch policy can reference it as a required check yet. That stops being true once it merges. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 24ef037b-246f-4fea-a1a3-4fae5223cb0c
The NDK version was pinned, but the way it was obtained was not. If the pool
image lacked the pinned version the step shelled out to sdkmanager, which
requires cmdline-tools on the image, prompts for licence acceptance, and
performs no integrity check on what it downloads.
Resolve it in two paths instead. Fast path: use the image's NDK, but only
after confirming source.properties reports exactly the pinned revision -- the
previous code inferred the version from the directory name alone. Otherwise
download Google's published archive and verify its SHA-1 before use.
The archive name and checksum become parameters alongside the version, since
all three come from one entry in Google's package manifest and have to move
together. A partially-updated triple cannot slip through: the extracted NDK's
Pkg.Revision is asserted against ndkVersion, so bumping the version without
the archive yields a checksum that still matches but a revision that does not.
Extraction uses unzip rather than python -m zipfile, which discards the
executable bit and would leave every toolchain binary unusable.
Also stop requiring an Android SDK to build. A cross-compile needs only the
NDK; the SDK is an emulator concern, so it is now resolved in a step guarded
by runEmulatorTests. This removes a hard dependency on pool image contents
that were never verified, and lets an image without an SDK still build.
Verified against the real toolchain and the live archive:
- pinned NDK on the image is detected and its revision asserted
- a different NDK version is rejected rather than silently used
- no NDK present falls through to the download path
- the URL returns HTTP 200, Content-Length 783549481 matching the manifest,
Content-Type application/zip, and PK\x03\x04 magic
- the archive's first entry is android-ndk-r29/, confirming the single
top-level directory the extraction assumes
- sha1sum parsing yields a 40-char digest and detects a mismatch
- all eight bash step bodies pass bash -n
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 24ef037b-246f-4fea-a1a3-4fae5223cb0c
sheetalarkadam
force-pushed
the
ci/android-native-build
branch
from
August 10, 2026 19:45
e5e03ea to
041407e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Android stages to CI
Scope / decisions
runEmulatorTestson the x86_64 leg.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.
.sofiles are staged (libfoundry_local.so,libonnxruntime.so,libonnxruntime-genai.so, andlibmat.so), unlike the desktop legs which stage onlylibfoundry_local.so. Desktop consumers get ORT/GenAI out of band (pip / NuGet); anAndroid consumer has no such channel. A
readelfDT_NEEDED-closure check fails thestage if a staged library needs a build-produced
.sothat wasn't staged.