Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ name: release
# resources.srcDir(nativeResourcesRoot) on jvmMain picks them all
# up into the published JAR.
#
# The publish job also builds and publishes the skainet-backend-jni-cpu AAR
# (Android JNI kernel provider). Its native .so's are cross-compiled by the
# NDK during `./gradlew publish`, so the publish runner sets up the Android
# SDK + a pinned NDK (see the publish job) — independent of the build-native
# matrix above, which only produces the FFM shared libs.
#
# Linux ARM64 is intentionally absent: Kotlin/Native plugin 2.3.21
# doesn't support `linux aarch64` as a HOST target ("Unknown host
# target" — see SKaiNET PR #577). Linux ARM64 consumers fall back
Expand Down Expand Up @@ -139,6 +145,20 @@ jobs:
distribution: 'zulu'
java-version: 25

# `./gradlew publish` now includes skainet-backend-jni-cpu (an Android
# library whose AAR carries NDK-built .so's). The publish runner therefore
# needs the Android SDK + a pinned NDK; without it the AAR's native build
# fails and the release ships no JNI artifact. The NDK version must match
# gradle/libs.versions.toml `android-ndk`.
- name: Set up Android SDK
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2

- name: Install pinned NDK
run: |
NDK_VERSION="$(grep -E '^android-ndk[[:space:]]*=' gradle/libs.versions.toml | sed -E 's/.*"([^"]+)".*/\1/')"
echo "Installing NDK ${NDK_VERSION}"
yes | sdkmanager "ndk;${NDK_VERSION}" >/dev/null

- name: Validate signing configuration
run: |
if ! grep -Eq '^[[:space:]]*signAllPublications[[:space:]]*=[[:space:]]*true[[:space:]]*$' gradle.properties; then
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## [Unreleased]

### CI

- **Release workflow publishes the `skainet-backend-jni-cpu` AAR.** `./gradlew publish` now
includes the Android JNI kernel module, whose AAR carries NDK-cross-built `.so`s; the publish
job gains Android SDK + a pinned NDK setup so the native build succeeds on the release runner
(previously the release would ship no JNI artifact, or fail). The NDK version is pinned in
`gradle/libs.versions.toml` (`android-ndk`) and referenced by the module's `ndkVersion` and the
workflow, so local and CI builds are reproducible. (#946)

### Added

- **NEON body for the Q4_0 matmul kernel.** `skainet_q4_0_matmul` was the only priority
Expand Down
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ kotlinxCoroutines = "1.11.0"
kotlinBrowser = "0.5.0"
android-minSdk = "24"
android-compileSdk = "36"
# NDK for skainet-backend-jni-cpu's externalNativeBuild. Pinned so the AAR's
# .so's build reproducibly on dev machines and the release runner. r28+ links
# 16 KB-page-aligned .so's by default (Android 15+ requirement).
android-ndk = "28.2.13676358"
kotlinxSerializationJson = "1.11.0"
ktorClientCore = "3.5.2"
ktorClientPlugins = "3.1.1"
Expand Down
3 changes: 3 additions & 0 deletions skainet-backends/skainet-backend-jni-cpu/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ plugins {
android {
namespace = "sk.ainet.exec.kernel.jni"
compileSdk = libs.versions.android.compileSdk.get().toInt()
// Pinned NDK so the AAR's .so's build reproducibly locally and on the
// release runner (AGP provisions it via sdkmanager when absent).
ndkVersion = libs.versions.android.ndk.get()

defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
Expand Down
Loading