kivyforge 3.0.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. kivyforge/__init__.py +9 -0
  2. kivyforge/artifacts/__init__.py +41 -0
  3. kivyforge/artifacts/cache.py +81 -0
  4. kivyforge/artifacts/collect.py +354 -0
  5. kivyforge/artifacts/download.py +125 -0
  6. kivyforge/artifacts/frameworks.py +240 -0
  7. kivyforge/artifacts/native_stage_util.py +346 -0
  8. kivyforge/artifacts/runtime.py +65 -0
  9. kivyforge/artifacts/verify.py +45 -0
  10. kivyforge/artifacts/wheels.py +89 -0
  11. kivyforge/bundle/__init__.py +1 -0
  12. kivyforge/bundle/pycompile.py +161 -0
  13. kivyforge/cli/__init__.py +52 -0
  14. kivyforge/cli/_common.py +62 -0
  15. kivyforge/cli/_platform.py +84 -0
  16. kivyforge/cli/build.py +111 -0
  17. kivyforge/cli/clean.py +135 -0
  18. kivyforge/cli/doctor.py +52 -0
  19. kivyforge/cli/init.py +612 -0
  20. kivyforge/cli/init_writer.py +716 -0
  21. kivyforge/cli/lock.py +261 -0
  22. kivyforge/cli/open_cmd.py +15 -0
  23. kivyforge/cli/package.py +134 -0
  24. kivyforge/cli/run.py +162 -0
  25. kivyforge/cli/status.py +20 -0
  26. kivyforge/cli/upgrade.py +314 -0
  27. kivyforge/config/__init__.py +46 -0
  28. kivyforge/config/errors.py +43 -0
  29. kivyforge/config/icons.py +60 -0
  30. kivyforge/config/loader.py +3079 -0
  31. kivyforge/config/model.py +817 -0
  32. kivyforge/doctor/__init__.py +19 -0
  33. kivyforge/doctor/checks_common.py +95 -0
  34. kivyforge/doctor/probe.py +357 -0
  35. kivyforge/doctor/result.py +41 -0
  36. kivyforge/lock/__init__.py +42 -0
  37. kivyforge/lock/_pip_shim.py +63 -0
  38. kivyforge/lock/find_links.py +182 -0
  39. kivyforge/lock/model.py +69 -0
  40. kivyforge/lock/pep751.py +111 -0
  41. kivyforge/lock/reader.py +30 -0
  42. kivyforge/lock/resolver.py +124 -0
  43. kivyforge/lock/wheelruntime/__init__.py +70 -0
  44. kivyforge/lock/wheelruntime/builder.py +280 -0
  45. kivyforge/lock/wheelruntime/model.py +94 -0
  46. kivyforge/lock/wheelruntime/native_binaries.py +127 -0
  47. kivyforge/lock/wheelruntime/pbs_github.py +133 -0
  48. kivyforge/lock/wheelruntime/profile.py +104 -0
  49. kivyforge/lock/wheelruntime/resolver.py +248 -0
  50. kivyforge/lock/wheelruntime/runtime.py +161 -0
  51. kivyforge/lock/wheelruntime/serialize.py +245 -0
  52. kivyforge/platforms/__init__.py +114 -0
  53. kivyforge/platforms/android/__init__.py +140 -0
  54. kivyforge/platforms/android/adb.py +215 -0
  55. kivyforge/platforms/android/bootstrap/__init__.py +7 -0
  56. kivyforge/platforms/android/bootstrap/contract.py +166 -0
  57. kivyforge/platforms/android/bootstrap/render.py +244 -0
  58. kivyforge/platforms/android/bootstrap/templates/androidtest/KivyforgeContractTest.java +76 -0
  59. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivy_bootstrap.py +50 -0
  60. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_bootstrap.py +54 -0
  61. kivyforge/platforms/android/bootstrap/templates/bootstrap_py/_kivyforge_selftest.py +97 -0
  62. kivyforge/platforms/android/bootstrap/templates/cpp/CMakeLists.txt +20 -0
  63. kivyforge/platforms/android/bootstrap/templates/cpp/main.c +150 -0
  64. kivyforge/platforms/android/bootstrap/templates/java/org/jnius/NativeInvocationHandler.java +48 -0
  65. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonActivity.java +75 -0
  66. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonBundle.java +132 -0
  67. kivyforge/platforms/android/bootstrap/templates/java/org/kivy/android/PythonService.java +189 -0
  68. kivyforge/platforms/android/bootstrap/templates/java/org/renpy/android/Hardware.java +276 -0
  69. kivyforge/platforms/android/bootstrap/templates/sdl2/LICENSE-SDL.txt +18 -0
  70. kivyforge/platforms/android/bootstrap/templates/sdl2/SDL_REVISION.txt +3 -0
  71. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDevice.java +22 -0
  72. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceBLESteamController.java +650 -0
  73. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceManager.java +698 -0
  74. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/HIDDeviceUSB.java +309 -0
  75. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDL.java +90 -0
  76. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLActivity.java +2120 -0
  77. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLAudioManager.java +514 -0
  78. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLControllerManager.java +856 -0
  79. kivyforge/platforms/android/bootstrap/templates/sdl2/org/libsdl/app/SDLSurface.java +405 -0
  80. kivyforge/platforms/android/bootstrap/templates/sdl3/LICENSE-SDL.txt +18 -0
  81. kivyforge/platforms/android/bootstrap/templates/sdl3/SDL_REVISION.txt +3 -0
  82. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDevice.java +21 -0
  83. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceBLESteamController.java +829 -0
  84. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceManager.java +698 -0
  85. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/HIDDeviceUSB.java +354 -0
  86. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDL.java +90 -0
  87. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLActivity.java +2240 -0
  88. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLAudioManager.java +126 -0
  89. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLControllerManager.java +1010 -0
  90. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLDummyEdit.java +66 -0
  91. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLInputConnection.java +136 -0
  92. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSensorManager.java +73 -0
  93. kivyforge/platforms/android/bootstrap/templates/sdl3/org/libsdl/app/SDLSurface.java +464 -0
  94. kivyforge/platforms/android/cli.py +1023 -0
  95. kivyforge/platforms/android/doctor.py +899 -0
  96. kivyforge/platforms/android/elf.py +148 -0
  97. kivyforge/platforms/android/generate/__init__.py +1 -0
  98. kivyforge/platforms/android/generate/manifest.py +261 -0
  99. kivyforge/platforms/android/generate/project.py +462 -0
  100. kivyforge/platforms/android/generate/services.py +187 -0
  101. kivyforge/platforms/android/gradle_wrapper/NOTICE +3 -0
  102. kivyforge/platforms/android/gradle_wrapper/SHA256SUMS +1 -0
  103. kivyforge/platforms/android/gradle_wrapper/gradle-wrapper.jar +0 -0
  104. kivyforge/platforms/android/gradle_wrapper/gradlew +164 -0
  105. kivyforge/platforms/android/gradle_wrapper/gradlew.bat +90 -0
  106. kivyforge/platforms/android/gradlew.py +60 -0
  107. kivyforge/platforms/android/icons.py +237 -0
  108. kivyforge/platforms/android/lock/__init__.py +1 -0
  109. kivyforge/platforms/android/lock/archives.py +109 -0
  110. kivyforge/platforms/android/lock/builder.py +387 -0
  111. kivyforge/platforms/android/lock/markers.py +71 -0
  112. kivyforge/platforms/android/lock/maven.py +252 -0
  113. kivyforge/platforms/android/lock/model.py +113 -0
  114. kivyforge/platforms/android/lock/python_meta.py +199 -0
  115. kivyforge/platforms/android/lock/reader.py +206 -0
  116. kivyforge/platforms/android/lock/resolver.py +276 -0
  117. kivyforge/platforms/android/lock/writer.py +121 -0
  118. kivyforge/platforms/android/policy.py +214 -0
  119. kivyforge/platforms/android/signing.py +145 -0
  120. kivyforge/platforms/android/smoke.py +43 -0
  121. kivyforge/platforms/android/splash.py +293 -0
  122. kivyforge/platforms/android/stage/__init__.py +1 -0
  123. kivyforge/platforms/android/stage/bundle.py +295 -0
  124. kivyforge/platforms/android/stage/jnilibs.py +186 -0
  125. kivyforge/platforms/android/stage/runtime.py +61 -0
  126. kivyforge/platforms/android/stage/wheels.py +106 -0
  127. kivyforge/platforms/android/toolchain.py +29 -0
  128. kivyforge/platforms/base.py +157 -0
  129. kivyforge/platforms/ios/__init__.py +129 -0
  130. kivyforge/platforms/ios/assets.py +193 -0
  131. kivyforge/platforms/ios/buildsettings.py +128 -0
  132. kivyforge/platforms/ios/cli.py +543 -0
  133. kivyforge/platforms/ios/doctor.py +410 -0
  134. kivyforge/platforms/ios/entitlements.py +34 -0
  135. kivyforge/platforms/ios/generator.py +318 -0
  136. kivyforge/platforms/ios/lock/__init__.py +71 -0
  137. kivyforge/platforms/ios/lock/builder.py +393 -0
  138. kivyforge/platforms/ios/lock/markers.py +69 -0
  139. kivyforge/platforms/ios/lock/model.py +95 -0
  140. kivyforge/platforms/ios/lock/python_meta.py +187 -0
  141. kivyforge/platforms/ios/lock/reader.py +191 -0
  142. kivyforge/platforms/ios/lock/resolver.py +304 -0
  143. kivyforge/platforms/ios/lock/spm.py +217 -0
  144. kivyforge/platforms/ios/lock/writer.py +114 -0
  145. kivyforge/platforms/ios/lock/xcframework.py +188 -0
  146. kivyforge/platforms/ios/materialize.py +59 -0
  147. kivyforge/platforms/ios/plist.py +91 -0
  148. kivyforge/platforms/ios/privacy.py +39 -0
  149. kivyforge/platforms/ios/skeleton.py +165 -0
  150. kivyforge/platforms/ios/sources.py +63 -0
  151. kivyforge/platforms/ios/staging.py +225 -0
  152. kivyforge/platforms/ios/swift_packages.py +324 -0
  153. kivyforge/platforms/ios/templates/kivyforge_bootstrap.h +34 -0
  154. kivyforge/platforms/ios/templates/kivyforge_bootstrap.m +146 -0
  155. kivyforge/platforms/ios/templates/main.m +15 -0
  156. kivyforge/platforms/ios/templates/main_config.h.in +12 -0
  157. kivyforge/platforms/ios/xcframeworks.py +194 -0
  158. kivyforge/platforms/ios/xcode/__init__.py +76 -0
  159. kivyforge/platforms/ios/xcode/commands.py +296 -0
  160. kivyforge/platforms/ios/xcode/runner.py +316 -0
  161. kivyforge/platforms/linux/__init__.py +120 -0
  162. kivyforge/platforms/linux/appimage.py +169 -0
  163. kivyforge/platforms/linux/bundle.py +235 -0
  164. kivyforge/platforms/linux/cli.py +232 -0
  165. kivyforge/platforms/linux/desktop.py +71 -0
  166. kivyforge/platforms/linux/doctor.py +438 -0
  167. kivyforge/platforms/linux/elftools.py +95 -0
  168. kivyforge/platforms/linux/icons.py +129 -0
  169. kivyforge/platforms/linux/launcher.py +107 -0
  170. kivyforge/platforms/linux/lock/__init__.py +126 -0
  171. kivyforge/platforms/linux/lock/profile.py +254 -0
  172. kivyforge/platforms/linux/lock/runtime.py +75 -0
  173. kivyforge/platforms/linux/native_stage.py +47 -0
  174. kivyforge/platforms/linux/runtime_stage.py +107 -0
  175. kivyforge/platforms/linux/wheels_stage.py +103 -0
  176. kivyforge/platforms/macos/__init__.py +121 -0
  177. kivyforge/platforms/macos/bundle.py +255 -0
  178. kivyforge/platforms/macos/cli.py +269 -0
  179. kivyforge/platforms/macos/doctor.py +480 -0
  180. kivyforge/platforms/macos/icns.py +75 -0
  181. kivyforge/platforms/macos/launcher.py +118 -0
  182. kivyforge/platforms/macos/lock/__init__.py +112 -0
  183. kivyforge/platforms/macos/lock/profile.py +119 -0
  184. kivyforge/platforms/macos/lock/runtime.py +58 -0
  185. kivyforge/platforms/macos/machotools.py +138 -0
  186. kivyforge/platforms/macos/native_stage.py +47 -0
  187. kivyforge/platforms/macos/notarize.py +143 -0
  188. kivyforge/platforms/macos/plist.py +37 -0
  189. kivyforge/platforms/macos/runtime_stage.py +110 -0
  190. kivyforge/platforms/macos/signing.py +78 -0
  191. kivyforge/platforms/macos/wheels_stage.py +108 -0
  192. kivyforge/platforms/windows/__init__.py +133 -0
  193. kivyforge/platforms/windows/assets.py +76 -0
  194. kivyforge/platforms/windows/bundle.py +298 -0
  195. kivyforge/platforms/windows/cli.py +314 -0
  196. kivyforge/platforms/windows/doctor.py +563 -0
  197. kivyforge/platforms/windows/fsswap.py +87 -0
  198. kivyforge/platforms/windows/icons.py +64 -0
  199. kivyforge/platforms/windows/launcher/__init__.py +193 -0
  200. kivyforge/platforms/windows/launcher/build_launcher.py +507 -0
  201. kivyforge/platforms/windows/launcher/launcher.c +379 -0
  202. kivyforge/platforms/windows/lock/__init__.py +112 -0
  203. kivyforge/platforms/windows/lock/profile.py +101 -0
  204. kivyforge/platforms/windows/lock/runtime.py +64 -0
  205. kivyforge/platforms/windows/naming.py +52 -0
  206. kivyforge/platforms/windows/native_stage.py +66 -0
  207. kivyforge/platforms/windows/petools.py +98 -0
  208. kivyforge/platforms/windows/rcedit.py +116 -0
  209. kivyforge/platforms/windows/runtime_stage.py +221 -0
  210. kivyforge/platforms/windows/signing.py +168 -0
  211. kivyforge/platforms/windows/vendor/LICENSE.rcedit +29 -0
  212. kivyforge/platforms/windows/vendor/NOTICE +17 -0
  213. kivyforge/platforms/windows/vendor/SHA256SUMS +4 -0
  214. kivyforge/platforms/windows/vendor/TOOLSET.txt +4 -0
  215. kivyforge/platforms/windows/vendor/__init__.py +12 -0
  216. kivyforge/platforms/windows/vendor/fetch_rcedit.py +97 -0
  217. kivyforge/platforms/windows/vendor/launcher-amd64.exe +0 -0
  218. kivyforge/platforms/windows/vendor/rcedit-x64.exe +0 -0
  219. kivyforge/platforms/windows/wheels_stage.py +139 -0
  220. kivyforge-3.0.0.dev0.dist-info/METADATA +609 -0
  221. kivyforge-3.0.0.dev0.dist-info/RECORD +225 -0
  222. kivyforge-3.0.0.dev0.dist-info/WHEEL +5 -0
  223. kivyforge-3.0.0.dev0.dist-info/entry_points.txt +3 -0
  224. kivyforge-3.0.0.dev0.dist-info/licenses/LICENSE +21 -0
  225. kivyforge-3.0.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,609 @@
1
+ Metadata-Version: 2.4
2
+ Name: kivyforge
3
+ Version: 3.0.0.dev0
4
+ Summary: Declarative, PEP 621-aligned build toolchain for Kivy apps — successor to kivy-ios, python-for-android, and buildozer (iOS, Android, macOS, Linux, and Windows)
5
+ Author-email: The Kivy Team <kivy-dev@googlegroups.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ElliotGarbus/kivyforge
8
+ Project-URL: Source, https://github.com/ElliotGarbus/kivyforge
9
+ Project-URL: Bug Reports, https://github.com/ElliotGarbus/kivyforge/issues
10
+ Keywords: kivy,ios,android,toolchain,packaging,mobile,buildozer
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Build Tools
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Operating System :: MacOS :: MacOS X
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Operating System :: Microsoft :: Windows
20
+ Requires-Python: >=3.13
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1
24
+ Requires-Dist: packaging>=24
25
+ Requires-Dist: pbxproj>=3.5
26
+ Requires-Dist: tomli-w>=1.1
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8; extra == "dev"
29
+ Requires-Dist: pytest-cov>=5; extra == "dev"
30
+ Requires-Dist: ruff>=0.9; extra == "dev"
31
+ Requires-Dist: Pillow>=10; extra == "dev"
32
+ Provides-Extra: linux
33
+ Requires-Dist: Pillow>=10; extra == "linux"
34
+ Provides-Extra: windows
35
+ Requires-Dist: Pillow>=10; extra == "windows"
36
+ Provides-Extra: android
37
+ Requires-Dist: Pillow>=10; extra == "android"
38
+ Dynamic: license-file
39
+
40
+ # kivyforge
41
+
42
+
43
+ [![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](https://opencollective.com/kivy)
44
+ [![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](https://opencollective.com/kivy)
45
+ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md)
46
+
47
+ ![PyPI - Version](https://img.shields.io/pypi/v/kivyforge)
48
+ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/kivyforge)
49
+
50
+ [![kivyforge](https://github.com/ElliotGarbus/kivyforge/actions/workflows/kivyforge.yml/badge.svg)](https://github.com/ElliotGarbus/kivyforge/actions/workflows/kivyforge.yml)
51
+
52
+ kivyforge is a declarative, [PEP 621](https://peps.python.org/pep-0621/)-aligned
53
+ build toolchain for [Kivy](https://kivy.org) (and other Python) apps. You
54
+ describe your app once in `pyproject.toml`; kivyforge resolves your dependencies
55
+ into a lockfile and packages the app for the platform you target. It is the
56
+ successor to **kivy-ios**, **python-for-android**, and **buildozer**, unifying
57
+ their per-platform workflows behind a single declarative configuration.
58
+
59
+ The goal is one toolchain for every platform Kivy runs on — **Android, iOS,
60
+ Linux, macOS, and Windows**.
61
+
62
+ > **Status: early development — iOS + macOS + Linux + Windows + Android.**
63
+ > kivyforge targets **iOS** (resolve into `pylock.ios.toml`, download the official
64
+ > [`Python.xcframework`](https://www.python.org/downloads/) + prebuilt iOS
65
+ > wheels, generate an [Xcode](https://developer.apple.com/xcode/) project),
66
+ > **macOS** (resolve into `pylock.macos.toml`, bundle a relocatable
67
+ > [python-build-standalone](https://github.com/astral-sh/python-build-standalone)
68
+ > CPython + wheels into a signed, double-clickable `.app`), **Linux** (resolve
69
+ > into `pylock.linux.toml`, bundle a PBS gnu/glibc CPython + manylinux wheels into
70
+ > an [AppImage](https://appimage.org/) — with a run-from-folder AppDir substrate),
71
+ > **Windows** (resolve into `pylock.windows.toml`, bundle a PBS MSVC CPython +
72
+ > `win_amd64` wheels into a run-from-folder `onedir` with a windowed launcher
73
+ > `.exe`, optionally Authenticode-signed), and **Android** (resolve into
74
+ > `pylock.android.toml`, assemble the official
75
+ > [python.org Android runtime](https://www.python.org/downloads/android/) +
76
+ > per-ABI `android_*` wheels into a generated Gradle project, and produce a
77
+ > signed `.apk`/`.aab` — with pyjnius as a prebuilt wheel, no per-app
78
+ > compilation). If you need a shipping toolchain today, use kivy-ios 2.x,
79
+ > python-for-android, or buildozer.
80
+
81
+ ### Currently supported targets
82
+
83
+ | Target | Architectures | Output | Signing | Build host |
84
+ |---|---|---|---|---|
85
+ | [iOS](https://www.apple.com/ios/) device | arm64 (iPhone / iPad) | generated Xcode project → `.app` | Apple Developer signing via Xcode | macOS + [Xcode](https://developer.apple.com/xcode/) |
86
+ | iOS Simulator | arm64 | generated Xcode project → `.app` | none required | macOS + Xcode |
87
+ | [Android](https://www.android.com/) device / emulator | `arm64_v8a`, `x86_64` | generated Gradle/AGP project → `.apk` / `.aab` | auto debug keystore, or release keystore (v1–v4 schemes) | Windows, macOS, or Linux + JDK/Android SDK/NDK |
88
+ | [macOS](https://www.apple.com/macos/) | arm64 (Apple Silicon) | `.app` | ad-hoc (default) **or** Developer ID sign + notarize + staple | macOS (Apple Silicon) |
89
+ | [Linux](https://appimage.org/) | x86_64 (glibc ≥ 2.17) | `.AppImage` / AppDir | none | Linux |
90
+ | [Windows](https://learn.microsoft.com/windows/) | amd64 | `onedir` folder + windowed launcher `.exe` | optional Authenticode (unsigned by default) | Windows |
91
+
92
+ Desktop targets (macOS / Linux / Windows) bundle a self-contained runtime +
93
+ wheels; on Linux, libGL/EGL and X11/Wayland come from the host. Building for iOS
94
+ requires a Mac with Xcode; Android builds on any of the three desktop hosts.
95
+
96
+ **Apple targets are Apple Silicon only.** kivyforge does not build Intel (`x86_64`)
97
+ macOS apps or pin the Intel iOS-Simulator slice: macOS 27 stops installing on
98
+ Intel hardware and macOS 28 removes Rosetta, so an Intel slice would be one
99
+ nothing can execute or validate. `universal2` *wheels* are still resolved
100
+ normally — they contain arm64.
101
+
102
+ kivyforge builds on the work of the [Kivy Team](https://kivy.org/about.html).
103
+
104
+ ## Requirements
105
+
106
+ Each target platform has its own host requirements. **Building for iOS requires
107
+ macOS** (Xcode-based), so the iOS workflow below is useful only on a Mac:
108
+
109
+ - macOS with [Xcode](https://developer.apple.com/xcode/) installed, either from
110
+ the [Mac App Store](https://apps.apple.com/app/xcode/id497799835) or from the
111
+ command line:
112
+
113
+ xcode-select --install
114
+
115
+ - Accept the Xcode license once:
116
+
117
+ sudo xcodebuild -license
118
+
119
+ **Building for Android** works from Windows, macOS, or Linux, and needs three
120
+ user-installed prerequisites (kivyforge never installs a host toolchain — it only
121
+ detects one):
122
+
123
+ - A **JDK 17+** on `PATH` or `JAVA_HOME`.
124
+ - The **Android SDK** (`ANDROID_HOME`/`ANDROID_SDK_ROOT`), with the `compile_sdk`
125
+ platform, build-tools, platform-tools, and accepted licenses
126
+ (`sdkmanager --licenses`). Android Studio's SDK Manager covers all of it.
127
+ - The **NDK** — required for *every* Android build, not just apps with native
128
+ code: it compiles the bootstrap's native launcher (`libmain.so`).
129
+
130
+ `kivyforge doctor -p android` checks each of these and prints the `sdkmanager`
131
+ command for whatever is missing. Add an AVD (or attach a device with USB debugging
132
+ enabled) before `kivyforge run`.
133
+
134
+ ## Installation
135
+
136
+ Use a Python virtual environment (host Python 3.13+). This is required: it
137
+ isolates the toolchain and keeps its lockfile resolution from being polluted by
138
+ packages in your system Python.
139
+
140
+ python3 -m venv .venv
141
+ . .venv/bin/activate
142
+
143
+ Install kivyforge from this repository (it is not yet published to PyPI):
144
+
145
+ pip install -e ".[dev]"
146
+
147
+ > **Mobile examples need no local wheel-building.** Kivy (2.3.1 and 3.0),
148
+ > pyobjus, and pyjnius resolve from the
149
+ > [kivy-mobile-wheels](https://github.com/ElliotGarbus/kivy-mobile-wheels)
150
+ > index — a companion repo of first-party iOS/Android cross-builds published as
151
+ > a static PEP 503 index — so `kivyforge lock` just works against any mobile
152
+ > example. `scripts/build_ios_wheels.sh` / `scripts/build_pyobjus_ios_wheels.sh`
153
+ > remain for cross-building your own iOS wheels locally (e.g. to vendor one via
154
+ > a `path` lock instead of the index); neither is required to run the examples.
155
+ >
156
+ > **Desktop needs no wheel-building either.** The desktop examples under
157
+ > [`examples/desktop/`](examples/desktop/) build straight from PyPI — Kivy
158
+ > 2.3.1 ships universal2 macOS wheels, so there is no macOS wheel-building
159
+ > step. Kivy 3.0 has no public desktop wheels yet, which is why desktop
160
+ > examples stay on 2.3.1; the iOS mobile examples need 3.0 for its structural
161
+ > mobile changes, while the Android examples run either generation (2.3.1/SDL2
162
+ > for most, 3.0/SDL3 for `hello-sdl3`) depending on which bootstrap they gate.
163
+
164
+ > **Detailed documentation.** For the full design and reference docs — the
165
+ > cross-platform model, the `pyproject.toml` / `pylock.<platform>.toml` schemas,
166
+ > artifact distribution, the CLI shape, and the per-platform backends (Android,
167
+ > iOS, macOS, Linux, Windows) — start with the
168
+ > [kivyforge design overview](docs/design/common/00-overview.md).
169
+
170
+ ## Quick start (iOS)
171
+
172
+ The workflow below targets iOS; see Quick start (Android), (macOS), (Linux),
173
+ and (Windows) further down for the other backends. Run every command from the
174
+ directory that contains your app's `pyproject.toml`.
175
+
176
+ # 1. Seed [tool.kivy] / [tool.kivy.ios] config into pyproject.toml
177
+ kivyforge init
178
+
179
+ # 2. Resolve dependencies into pylock.ios.toml
180
+ kivyforge lock
181
+
182
+ # 3. Download artifacts and generate <app>-ios/<app>.xcodeproj
183
+ kivyforge build
184
+
185
+ # 4a. Open the project in Xcode and press Run...
186
+ kivyforge open
187
+
188
+ # 4b. ...or build, install, and launch on the simulator from the CLI
189
+ kivyforge build --simulator
190
+ kivyforge run --simulator
191
+
192
+ ## Quick start (macOS)
193
+
194
+ macOS needs only the Xcode command-line tools (`codesign`), not the full Xcode
195
+ IDE. The macOS backend bundles a relocatable CPython + your wheels into a signed
196
+ `.app`:
197
+
198
+ # 1. Seed [tool.kivy] / [tool.kivy.macos] config (or add the overlay by hand)
199
+ kivyforge init # then add a [tool.kivy.macos] table
200
+
201
+ # 2. Resolve dependencies + pin the runtime into pylock.macos.toml
202
+ kivyforge lock -p macos
203
+
204
+ # 3. Build the .app (arm64)
205
+ kivyforge build -p macos
206
+
207
+ # 4a. Launch it (foreground, so you see stdout/tracebacks)
208
+ kivyforge run -p macos
209
+
210
+ # 4b. ...or produce the finished, signed distributable
211
+ kivyforge package -p macos # -> build/macos/<App>.app
212
+
213
+ `package` is config-driven: with no signing config it ships the **ad-hoc**-signed
214
+ `.app` (runs locally; downloaded copies hit Gatekeeper). For distribution to
215
+ other Macs, configure `[tool.kivy.macos.signing]` with a *Developer ID
216
+ Application* identity (paid Apple Developer Program) and a `notary_profile`
217
+ (created with `xcrun notarytool store-credentials`) — then the same command
218
+ deep-signs with Hardened Runtime, **notarizes, and staples** the `.app` so
219
+ Gatekeeper trusts it everywhere. `--no-notarize` skips the submission. (Hit
220
+ `errSecInternalComponent` from `codesign`? See the
221
+ [FAQ entry](FAQ.md#macos-developer-id-signing-fails-with-errsecinternalcomponent)
222
+ on corrupted keychain ACLs.)
223
+
224
+ `kivyforge doctor -p macos` reports environment + project health (host, codesign,
225
+ arch coverage, runtime floor, signing identity, notary setup, reachable hosts).
226
+
227
+ ## Quick start (Linux)
228
+
229
+ The Linux backend bundles a relocatable CPython + your manylinux wheels into an
230
+ [AppImage](https://appimage.org/) (the default) or a run-from-folder **AppDir**.
231
+ It needs a Linux host (the runtime is a gnu/glibc build); no compiler or FUSE is
232
+ required at build time.
233
+
234
+ # 1. Add a [tool.kivy.linux] table to pyproject.toml (app_id, icons, ...)
235
+
236
+ # 2. Resolve dependencies + pin the runtime into pylock.linux.toml
237
+ kivyforge lock -p linux
238
+
239
+ # 3. Build the AppDir (build/linux/<App>.AppDir)
240
+ kivyforge build -p linux
241
+
242
+ # 4a. Launch it (runs ./AppRun directly — the fast dev loop, no FUSE)
243
+ kivyforge run -p linux
244
+
245
+ # 4b. ...or produce the distributable
246
+ kivyforge package -p linux # -> dist/linux/<app>-<ver>-x86_64.AppImage
247
+ kivyforge package -p linux -f folder # -> the AppDir itself
248
+
249
+ The AppImage embeds a **static-FUSE runtime**, so recipients need no `libfuse2`;
250
+ `./<App>.AppImage --appimage-extract-and-run` is the universal no-FUSE fallback.
251
+ The **host contract** is explicit: the bundle never vendors libGL/libEGL or a
252
+ display server, so the host must provide glibc ≥ the artifact's effective floor,
253
+ `libGL.so.1`/`libEGL.so.1`, and an X11 or Wayland session.
254
+
255
+ `kivyforge doctor -p linux` reports environment + project health (Linux/glibc
256
+ host, GL libraries, display session, glibc floor, arch coverage, generated
257
+ `.desktop` validity, reachable hosts).
258
+
259
+ ## Quick start (Windows)
260
+
261
+ The Windows backend bundles a relocatable CPython + your `win_amd64` wheels into
262
+ a run-from-folder **`onedir`**: a windowed launcher `.exe` beside a full
263
+ python-build-standalone prefix, your app source, and any declared native
264
+ binaries. It needs a Windows host (the runtime is an MSVC amd64 build and the
265
+ resource/signing tools are Windows-only); no compiler is required at build time.
266
+
267
+ # 1. Add a [tool.kivy.windows] table to pyproject.toml (app_id, icons, ...)
268
+
269
+ # 2. Resolve dependencies + pin the runtime into pylock.windows.toml
270
+ kivyforge lock -p windows
271
+
272
+ # 3. Build the onedir bundle (build\windows\<App>\)
273
+ kivyforge build -p windows
274
+
275
+ # 4a. Launch it (runs the launcher .exe in the foreground — the dev loop)
276
+ kivyforge run -p windows
277
+
278
+ # 4b. ...or produce the distributable (copied to dist\windows\)
279
+ kivyforge package -p windows # -> dist\windows\<app>-<ver>-amd64\
280
+
281
+ Double-clicking the launcher opens the app with **no console flash**; `kivyforge
282
+ run` attaches it to the terminal so stdout/stderr and tracebacks are visible. The
283
+ `onedir` folder keeps every file real and signable — installers stay external.
284
+ **Authenticode signing** is optional and off by default: configure
285
+ `[tool.kivy.windows.signing]` with a certificate-store `thumbprint` and `package`
286
+ signs (and RFC-3161 timestamps) the launcher in the `dist\windows` copy.
287
+
288
+ `kivyforge doctor -p windows` reports environment + project health (Windows host,
289
+ long-path support, `app_id` style, arch coverage, icon, native-binary
290
+ sources/collisions/arch, build-output lock, build volume (Dev Drive advisory),
291
+ reachable hosts, signtool + signing certificate).
292
+
293
+ ## Quick start (Android)
294
+
295
+ The Android backend assembles the official
296
+ [python.org Android runtime](https://www.python.org/downloads/android/) + your
297
+ `android_*` wheels into a generated **Gradle/AGP** project and produces a
298
+ signed **`.apk`** (sideload/CI) or **`.aab`** (Play upload) — a wheel-assembly
299
+ and Gradle-drive backend, no python-for-android recipe system, no per-app C
300
+ compilation. It needs a JDK, the Android SDK, and the NDK, but builds on
301
+ Windows, macOS, or Linux. 64-bit only (`arm64_v8a`, `x86_64`).
302
+
303
+ # 1. Seed [tool.kivy] + [tool.kivy.android] into pyproject.toml
304
+ kivyforge init -p android # then set `package`, kivy_generation, ...
305
+
306
+ # 2. Resolve dependencies + pin the runtime into pylock.android.toml
307
+ kivyforge lock -p android
308
+
309
+ # 3. Generate the Gradle project (<app>-android/) and assemble a debug APK
310
+ kivyforge build -p android --debug # -> <app>-android/app/build/outputs/apk/debug/
311
+
312
+ # 4a. Install and launch on a connected device or emulator
313
+ kivyforge run -p android --emulator
314
+
315
+ # 4b. ...or produce the signed release distributable
316
+ kivyforge package -p android # -> <app>-android/app/build/outputs/apk/release/
317
+ kivyforge package -p android -f aab # -> .../outputs/bundle/release/ (Play upload)
318
+
319
+ Without `--debug`, step 3 stops after generating the project — ready to open in
320
+ Android Studio (`kivyforge open -p android`) or to drive `gradlew` by hand.
321
+
322
+ `kivy_generation = 2` targets Kivy 2.3.1 (SDL2, stable); `kivy_generation = 3`
323
+ targets Kivy 3.0 (SDL3, pre-release) — mutually exclusive per app, and the SDL
324
+ Java glue + `libSDL*.so` must come from the same release (`kivyforge build`
325
+ fails fast on a mismatch rather than the silent black-screen failure that
326
+ would otherwise produce).
327
+ Debug builds sign with an auto-managed debug keystore; `package` requires a
328
+ configured release keystore (`[tool.kivy.android.signing]`, passwords from
329
+ environment variables, never in `pyproject.toml`).
330
+
331
+ `kivyforge doctor -p android` reports environment + project health
332
+ (JDK/SDK/build-tools/NDK/emulator/adb, the SDL↔Kivy pairing, the pyjnius
333
+ `invoke0` contract, a hermetic 16 KB page-alignment scanner, ABI coverage,
334
+ signing, lock-host reachability). `kivyforge run --smoke` runs a generated
335
+ instrumented contract test on a real device/emulator — validated on an x86_64
336
+ API-31 emulator and a Pixel 8a (Android 16 / API 36) for both SDL2 and SDL3.
337
+
338
+ See the runnable examples for complete, copy-pasteable walk-throughs. They are
339
+ split by runtime requirement — **desktop uses Kivy 2.3.1 from PyPI, mobile
340
+ resolves Kivy (2.3.1 and 3.0) from the
341
+ [kivy-mobile-wheels](https://github.com/ElliotGarbus/kivy-mobile-wheels)
342
+ index**:
343
+
344
+ **Desktop** ([`examples/desktop/`](examples/desktop/)) — macOS/Linux/Windows:
345
+
346
+ - [`dice-roller`](examples/desktop/dice-roller/) — minimal Kivy UI that **builds &
347
+ runs on macOS, Linux, and Windows today** from PyPI (Kivy 2.3.1).
348
+ - [`notes`](examples/desktop/notes/) — Kivy app with a pure-Python dependency
349
+ (`platformdirs`); builds on macOS, Linux, and Windows from PyPI.
350
+ - [`desktop-viewer`](examples/desktop/desktop-viewer/) — a **macOS-only** Kivy app
351
+ (resizable window, ⌘ keyboard shortcuts, and Finder's native open panel via
352
+ `osascript`); no Linux/Windows overlay.
353
+ - [`hello-native`](examples/desktop/hello-native/) — ships **non-wheel** native
354
+ binaries (a helper executable + a shared library) via
355
+ `[tool.kivy.<platform>.native.binaries]`; builds and runs on macOS, Linux, and
356
+ Windows (`greet.dll` loaded by name, `roll.exe` run by name).
357
+
358
+ **Mobile** ([`examples/mobile/`](examples/mobile/)) — iOS and Android; iOS on
359
+ Kivy 3.0, Android on either generation (wheels from
360
+ [`kivy-mobile-wheels`](https://github.com/ElliotGarbus/kivy-mobile-wheels)):
361
+
362
+ *iOS:*
363
+
364
+ - [`hello-world`](examples/mobile/hello-world/) — Kivy-free toolchain smoke test;
365
+ no dependencies, no wheels (builds on iOS via the python.org `Python.xcframework`;
366
+ the first example to bring up a new backend).
367
+ - [`hello-kivy`](examples/mobile/hello-kivy/) — minimal Kivy 3.0 UI.
368
+ - [`mobile-geometry`](examples/mobile/mobile-geometry/) — showcases the
369
+ `kivy.mobile` runtime-geometry API (DPI, safe-area insets, keyboard height).
370
+ - [`svg-explorer`](examples/mobile/svg-explorer/) — interactive SVG viewer
371
+ (multitouch pan/zoom/rotate).
372
+ - [`pyobjus-ball`](examples/mobile/pyobjus-ball/) — calls native iOS APIs
373
+ (CoreMotion, UIScreen) from Python via the Objective-C runtime.
374
+ - [`pyobjus-deviceinfo`](examples/mobile/pyobjus-deviceinfo/) — reads native iOS
375
+ device info (model, system version, battery) via pyobjus; a CPython 3.15
376
+ pre-release example.
377
+ - [`keychain-spm`](examples/mobile/keychain-spm/) — declares a remote Swift Package
378
+ (`KeychainAccess`), pins it with `kivyforge lock`, and calls it from Python
379
+ through a local `@objc` shim package.
380
+
381
+ *Android:*
382
+
383
+ - [`hello-android`](examples/mobile/hello-android/) — the smallest kivyforge
384
+ Android app (a single `Label`); the Kivy 2.3.1 / SDL2 on-device gate.
385
+ - [`hello-sdl3`](examples/mobile/hello-sdl3/) — the same app on **Kivy 3.0 /
386
+ SDL3**; deliberately identical to `hello-android` apart from the SDL
387
+ generation, and the SDL3 on-device gate.
388
+ - [`pyjnius-deviceinfo`](examples/mobile/pyjnius-deviceinfo/) — reads Android
389
+ device info (`Build`, `BatteryManager`, display metrics) via pyjnius, no
390
+ Java written.
391
+ - [`qr-maven`](examples/mobile/qr-maven/) — renders a QR code with Google's
392
+ ZXing, resolved as a Gradle/Maven coordinate (channel 4) and driven from
393
+ Python via a pyjnius `invoke0` round-trip.
394
+
395
+ ## Configuring your app
396
+
397
+ Your app is described declaratively in `pyproject.toml`. Standard
398
+ [PEP 621](https://peps.python.org/pep-0621/) `[project]` metadata supplies the
399
+ name, version, and runtime `dependencies`; shared, platform-neutral settings live
400
+ under `[tool.kivy]`, and iOS-specific settings live under `[tool.kivy.ios]`
401
+ (other platforms will add their own `[tool.kivy.<platform>]` tables):
402
+
403
+ ```toml
404
+ [project]
405
+ name = "hello-world"
406
+ version = "0.1.0"
407
+ requires-python = ">=3.15.0b4"
408
+ dependencies = [] # PyPI/local deps resolved into the lockfile
409
+
410
+ [tool.kivy]
411
+ display_name = "Hello World" # name shown under the icon
412
+ app_dir = "src" # folder containing your Python source
413
+ entry_point = "main" # module imported at launch (main.py)
414
+ orientation = ["portrait"]
415
+
416
+ [tool.kivy.ios]
417
+ bundle_id = "org.example.hello-world" # reverse-DNS; UTI characters only (no underscores)
418
+ build = 1
419
+ deployment_target = "13.0"
420
+ # find_links = ["../../wheels/ios"] # repo-relative wheel directory for lock
421
+ # exclude = ["docutils", "pygments"] # drop transitive deps you don't use at runtime
422
+
423
+ [tool.kivy.ios.python]
424
+ version = "3.15.0b4" # python.org Python.xcframework version
425
+
426
+ [tool.kivy.ios.signing]
427
+ team_id = "" # Apple Developer Team ID (device / release builds)
428
+ identity = "Apple Development"
429
+ auto_signing = true
430
+ ```
431
+
432
+ `kivyforge build` syncs your `app_dir` into the generated `<app>-ios/` tree on
433
+ every run, so make changes in your source folder (e.g. `src/`), never in the
434
+ generated project.
435
+
436
+ Kivy's wheel declares dependencies that are not all needed at runtime on iOS.
437
+ The `exclude` list trims them; the
438
+ [hello-kivy example](examples/mobile/hello-kivy/pyproject.toml) documents what each one
439
+ is for, so you can re-enable only the few that map to widgets you actually use
440
+ (e.g. `docutils` for `RSTDocument`, `pygments` for `CodeInput`, or `requests`
441
+ for `UrlRequest`).
442
+
443
+ ## Commands
444
+
445
+ The verbs are platform-neutral; each resolves a target from `-p/--platform`, the
446
+ `KIVYFORGE_PLATFORM` environment variable, or the host default, and then does the
447
+ platform's version of the same job.
448
+
449
+ kivyforge init Seed [tool.kivy] + the target's overlay into pyproject.toml
450
+ kivyforge lock Generate pylock.<platform>.toml from pyproject.toml
451
+ kivyforge build Download artifacts, generate the native project, build
452
+ kivyforge run Build (unless --no-build), install, and launch the app
453
+ kivyforge package Produce the signed, distributable artifact
454
+ kivyforge open Open the generated project in Xcode / Android Studio
455
+ kivyforge status Show app identity, Python version, lock sync, build state
456
+ kivyforge clean Remove generated artifacts in the project folder
457
+ kivyforge upgrade Re-fetch the pinned runtime and native artifacts
458
+ kivyforge doctor Run environment and project health checks
459
+
460
+ Run `kivyforge <command> -h` (or `kf <command> -h`) for the full set of
461
+ options on any verb. A few common ones:
462
+
463
+ - `kivyforge lock --check` — CI pre-flight; exits non-zero if the lock is stale.
464
+ - `kivyforge build --simulator | --device | --release` (iOS) — pick the build flavor.
465
+ - `kivyforge build --debug [--abi arm64_v8a|x86_64]` (Android) — assemble a debug APK, optionally for one ABI.
466
+ - `kivyforge run --list-devices` — list available simulators/emulators and devices.
467
+ - `kivyforge run --smoke` (Android) — run the generated on-device contract test.
468
+ - `kivyforge clean --cache` — also flush the artifact download cache.
469
+
470
+ Downloaded artifacts (`Python.xcframework`, the per-ABI Android runtime,
471
+ `.aar`/`.jar`s, runtime archives) are cached per-user and shared across projects.
472
+
473
+ ## Typical workflow
474
+
475
+ A normal session is a one-time setup followed by a tight edit → run loop. You only
476
+ re-run `kivyforge lock` when dependencies change, and `kivyforge build` when you
477
+ change app config (or need to regenerate the native project).
478
+
479
+ How cheap the inner loop is depends on the platform. On **iOS** the generated
480
+ project *links* your source directory (`app/` is a symlink to `app_dir`), so
481
+ editing Python source needs no rebuild — just relaunch. On **Android** the app's
482
+ code is packed into the APK's asset bundle, so a source edit needs a re-pack:
483
+ `kivyforge run` does that for you every iteration, which is why the Android loop
484
+ goes through `run` rather than a bare relaunch.
485
+
486
+ ```mermaid
487
+ flowchart TD
488
+ A["kivyforge init<br/>seed pyproject.toml"] --> B["Edit pyproject.toml<br/>dependencies + app config"]
489
+ B --> C["Write your app<br/>src/main.py"]
490
+ C --> D["kivyforge lock<br/>→ pylock.&lt;platform&gt;.toml"]
491
+ D --> E["kivyforge build<br/>fetch artifacts + generate the native project"]
492
+ E --> F{"Launch it"}
493
+ F -->|from the CLI| G["kivyforge run<br/>--simulator / --emulator / --device"]
494
+ F -->|from the IDE| H["kivyforge open → Xcode ⌘R / Android Studio Run"]
495
+ G --> I(["Iterate"])
496
+ H --> I
497
+ I -->|changed Python source| F
498
+ I -->|changed app config| E
499
+ I -->|changed dependencies| D
500
+ ```
501
+
502
+ Supporting commands fit around this loop: `kivyforge status` shows whether your
503
+ lock and build are current, `kivyforge doctor` diagnoses environment problems,
504
+ `kivyforge upgrade` re-fetches the pinned runtime, and `kivyforge clean` resets
505
+ the generated project when you want a fresh build.
506
+
507
+ ## Development
508
+
509
+ Clone the repository and install it into a virtual environment:
510
+
511
+ git clone https://github.com/ElliotGarbus/kivyforge.git
512
+ cd kivyforge/
513
+ python3 -m venv .venv
514
+ . .venv/bin/activate
515
+ pip install -e ".[dev]"
516
+
517
+ Run the test suite and the linter:
518
+
519
+ pytest
520
+ ruff check .
521
+
522
+ ## FAQ
523
+
524
+ For troubleshooting advice and other frequently asked questions, consult
525
+ the latest
526
+ [kivyforge FAQ](https://github.com/ElliotGarbus/kivyforge/blob/master/FAQ.md).
527
+
528
+ ## License
529
+
530
+ kivyforge is [MIT licensed](LICENSE), and builds on work actively developed by a
531
+ great community and supported by many projects managed by the
532
+ [Kivy Organization](https://www.kivy.org/about.html).
533
+
534
+ ## Support
535
+
536
+ Are you having trouble using kivyforge or any of its related projects in the Kivy
537
+ ecosystem?
538
+ Is there an error you don’t understand? Are you trying to figure out how to use
539
+ it? We have volunteers who can help!
540
+
541
+ The best channels to contact us for support are listed in the latest
542
+ [Contact Us](https://github.com/ElliotGarbus/kivyforge/blob/master/CONTACT.md) document.
543
+
544
+ ## Contributing
545
+
546
+ kivyforge builds on the [Kivy](https://kivy.org) ecosystem - a large group of
547
+ products used by many thousands of developers for free, but it
548
+ is built entirely by the contributions of volunteers. We welcome (and rely on)
549
+ users who want to give back to the community by contributing to the project.
550
+
551
+ Contributions can come in many forms. See the latest
552
+ [Contribution Guidelines](https://github.com/ElliotGarbus/kivyforge/blob/master/CONTRIBUTING.md)
553
+ for how you can help us.
554
+
555
+ ## Code of Conduct
556
+
557
+ In the interest of fostering an open and welcoming community, we as
558
+ contributors and maintainers need to ensure participation in our project and
559
+ our sister projects is a harassment-free and positive experience for everyone.
560
+ It is vital that all interaction is conducted in a manner conveying respect,
561
+ open-mindedness and gratitude.
562
+
563
+ Please consult the [latest Kivy Code of Conduct](https://github.com/kivy/kivy/blob/master/CODE_OF_CONDUCT.md).
564
+
565
+ ## Contributors
566
+
567
+ This project exists thanks to
568
+ [all the people who contribute](https://github.com/ElliotGarbus/kivyforge/graphs/contributors).
569
+ [[Become a contributor](CONTRIBUTING.md)].
570
+
571
+ <img src="https://contrib.nn.ci/api?repo=ElliotGarbus/kivyforge&pages=5&no_bot=true&radius=22&cols=18">
572
+
573
+ ## Backers
574
+
575
+ Thank you to [all of our backers](https://opencollective.com/kivy)!
576
+ 🙏 [[Become a backer](https://opencollective.com/kivy#backer)]
577
+
578
+ <img src="https://opencollective.com/kivy/backers.svg?width=890&avatarHeight=44&button=false">
579
+
580
+ ## Sponsors
581
+
582
+ Special thanks to
583
+ [all of our sponsors, past and present](https://opencollective.com/kivy).
584
+ Support this project by
585
+ [[becoming a sponsor](https://opencollective.com/kivy#sponsor)].
586
+
587
+ Here are our top current sponsors. Please click through to see their websites,
588
+ and support them as they support us.
589
+
590
+ <!--- See https://github.com/orgs/kivy/discussions/15 for explanation of this code. -->
591
+ <a href="https://opencollective.com/kivy/sponsor/0/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/0/avatar.svg"></a>
592
+ <a href="https://opencollective.com/kivy/sponsor/1/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/1/avatar.svg"></a>
593
+ <a href="https://opencollective.com/kivy/sponsor/2/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/2/avatar.svg"></a>
594
+ <a href="https://opencollective.com/kivy/sponsor/3/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/3/avatar.svg"></a>
595
+
596
+ <a href="https://opencollective.com/kivy/sponsor/4/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/4/avatar.svg"></a>
597
+ <a href="https://opencollective.com/kivy/sponsor/5/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/5/avatar.svg"></a>
598
+ <a href="https://opencollective.com/kivy/sponsor/6/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/6/avatar.svg"></a>
599
+ <a href="https://opencollective.com/kivy/sponsor/7/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/7/avatar.svg"></a>
600
+
601
+ <a href="https://opencollective.com/kivy/sponsor/8/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/8/avatar.svg"></a>
602
+ <a href="https://opencollective.com/kivy/sponsor/9/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/9/avatar.svg"></a>
603
+ <a href="https://opencollective.com/kivy/sponsor/10/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/10/avatar.svg"></a>
604
+ <a href="https://opencollective.com/kivy/sponsor/11/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/11/avatar.svg"></a>
605
+
606
+ <a href="https://opencollective.com/kivy/sponsor/12/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/12/avatar.svg"></a>
607
+ <a href="https://opencollective.com/kivy/sponsor/13/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/13/avatar.svg"></a>
608
+ <a href="https://opencollective.com/kivy/sponsor/14/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/14/avatar.svg"></a>
609
+ <a href="https://opencollective.com/kivy/sponsor/15/website" target="_blank"><img src="https://opencollective.com/kivy/sponsor/15/avatar.svg"></a>