Prebuilt runtimes and wheels¶
kivyforge never builds Python or its C extensions from source. It assembles prebuilt pieces. This explains which dependencies your app can use on each target.
The core rule: no from-source builds¶
kivyforge has no recipe system and does not cross-compile Python C extensions. Instead, it:
- downloads a prebuilt, relocatable Python runtime for the target, and
- installs prebuilt, platform-tagged wheels,
then leaves any genuine compilation to the platform's own toolchain, for example Xcode's Swift Package Manager for Swift packages. This keeps builds fast and reproducible.
Where runtimes come from¶
Each target uses an official or well-maintained prebuilt CPython:
- iOS: the official python.org
Python.xcframework. - Android: the official python.org Android runtime, one per ABI (application binary interface).
- macOS, Linux, and Windows: a relocatable python-build-standalone CPython, bundled into the app.
You choose the version in the overlay's python table. For example:
[tool.kivy.macos.python]
version = "3.13.14"
What this means for your dependencies¶
Each dependency must be available as a wheel for the target's platform tag:
- Desktop targets use ordinary PyPI wheels:
macosx_*(arm64 or universal2),manylinux_*, andwin_amd64. - iOS uses wheels with
ios_*platform tags. - Android uses wheels with
android_*platform tags, one per ABI.
A pure-Python dependency works everywhere. A dependency with a C extension works
only where a matching wheel exists. If no wheel exists for a target, kivyforge
cannot build one from source, and kivyforge lock fails to resolve it.
Mobile wheels for Kivy¶
Kivy, pyjnius, and pyobjus are published as first-party prebuilt iOS and
Android wheels on the
kivy-mobile-wheels index
until they land on PyPI. Add the index with extra_index_urls in the mobile
overlay, as the mobile examples do:
[tool.kivy.android]
extra_index_urls = ["https://elliotgarbus.github.io/kivy-mobile-wheels/simple/"]
Integrity¶
Every artifact is pinned by SHA-256 in the lockfile and verified on download. A
mismatch fails the build. Downloads are cached in a per-user cache shared by all
your projects. To empty it, run kivyforge clean --cache. pip keeps a separate
cache for what lock resolves, which that leaves alone; pip cache purge
clears it.
What's next¶
- Manage dependencies and re-lock.
- Ship native binaries that are not wheels.
- Lockfiles.