Skip to content

Cache Kotlin/Native library caches in iOS KMP PR checks - #125

Merged
matejsemancik merged 3 commits into
mainfrom
feature/kmp-native-klib-cache
Oct 7, 2026
Merged

matejsemancik merged 3 commits into
mainfrom
feature/kmp-native-klib-cache

Conversation

@matejsemancik

@matejsemancik matejsemancik commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Why

Debug framework links build a native cache for every library dependency in ~/.konan/kotlin-native-prebuilt-*/klib/cache. KMP projects run on self-hosted runners that start from a fresh VM, so every PR check rebuilds all of them inside the link task.

Measured on a project that renders Compose Multiplatform on iOS (126 library dependencies, linkDebugFrameworkIosSimulatorArm64 only):

Link Time
Cold (fresh VM, as on CI today) 246 s locally, ~4m40s on CI
Warm (library caches present) 28 s
Native cache disabled (disableNativeCache) 107 s

The Kotlin docs recommend preserving ~/.konan between CI builds: Preserve downloaded and cached components between builds.

What

ios-kmp-selfhosted-test gets a kotlin_native_cache input, enabled by default, so every KMP project gets the cache once it bumps to the release with this change. It adds an actions/cache@v6 step before Build KMP Package:

  • Path: ~/.konan/kotlin-native-prebuilt-*/klib/cache/*-user*, only the library caches built during the link (~340 MB for the measured project's simulator slice). The compiler distribution and LLVM are left out: downloading them takes ~16 s, and restoring ~1.3 GB more would cost about as much.
  • Key: OS, CPU architecture and libs.versions.toml, with no restore-keys fallback. Library caches live in per-version folders, so a partial restore would carry outdated versions into every new cache.
  • Saving: actions/cache saves at the end of the job, only on a key miss and only when the job succeeds.

Release builds don't use these caches, so nightly and release workflows are unaffected.

Impact on projects: no changes needed beyond the version bump. Each project stores one cache entry per libs.versions.toml state (a few hundred MB, depending on its dependencies) in its 10 GB repo cache budget. A project can opt out with kotlin_native_cache: false.

Sharing the cache across PRs

A cache saved in a PR run is only visible to later runs of that PR. To let every PR restore it, projects can also run their check on push to develop (push: branches: [ develop ], with the concurrency group using github.head_ref || github.ref). Change detection (dorny/paths-filter), the iOS Fastlane test lane and the Android Danger step all handle push events.

Testing

Planned on a consumer project's PR pointed at this branch (no input needed now that it's on by default): the first run should miss and save, and a second run after a UI-only change should restore the cache and link in ~30–40 s.

Debug framework links build a native cache for every library dependency in
~/.konan/.../klib/cache. Self-hosted runners start from a fresh VM, so every PR
check rebuilt them: ~4 of the ~4m40s link in uniapp-kmp (Compose Multiplatform),
against 28s with the caches present.

The new opt-in `kotlin_native_cache` input caches only those library caches
(~340 MB), keyed on libs.versions.toml without a restore-keys fallback so outdated
library versions do not accumulate. The compiler distribution and LLVM (~16s to
download) are left out: restoring them would cost about as much as it saves.
@matejsemancik
matejsemancik marked this pull request as draft October 7, 2026 12:55
@matejsemancik
matejsemancik marked this pull request as ready for review October 7, 2026 13:41
@matejsemancik
matejsemancik requested a review from Syntey October 7, 2026 13:41
@matejsemancik
matejsemancik marked this pull request as draft October 7, 2026 13:47
@matejsemancik matejsemancik reopened this Oct 7, 2026
@matejsemancik
matejsemancik marked this pull request as ready for review October 7, 2026 14:07
@matejsemancik
matejsemancik requested a review from ssestak October 7, 2026 14:19
@matejsemancik
matejsemancik merged commit 8133df8 into main Oct 7, 2026
4 checks passed
@matejsemancik
matejsemancik deleted the feature/kmp-native-klib-cache branch October 7, 2026 14:47
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.

2 participants