|
| 1 | +PEP: 9999 |
| 2 | +Title: Cross-compiling Python packages |
| 3 | +Author: Filipe Laíns <lains@python.org> |
| 4 | +PEP-Delegate: |
| 5 | +Discussions-To: [URL] |
| 6 | +Status: Draft |
| 7 | +Type: Informational |
| 8 | +Content-Type: text/x-rst |
| 9 | +Created: 01-07-2023 |
| 10 | +Python-Version: 3.12 |
| 11 | +Post-History: [`DD-MMM-YYYY <URL>`__] |
| 12 | +Resolution: |
| 13 | + |
| 14 | + |
| 15 | +Abstract |
| 16 | +======== |
| 17 | + |
| 18 | +This PEP attempts to document the status of cross-compilation of downstream |
| 19 | +projects, more specifically |
| 20 | + |
| 21 | +It should give an overview of the approaches currently used by distributors |
| 22 | +(Linux distros, WASM environment providers, etc.) to cross-compile downstream |
| 23 | +projects (3rd party extensions, etc.). |
| 24 | + |
| 25 | + |
| 26 | +Motivation |
| 27 | +========== |
| 28 | + |
| 29 | +We write this PEP to express the challenges in cross-compilation and act as a |
| 30 | +supporting document in future improvement proposals. |
| 31 | + |
| 32 | + |
| 33 | +Analysis |
| 34 | +======== |
| 35 | + |
| 36 | + |
| 37 | +Introduction |
| 38 | +------------ |
| 39 | + |
| 40 | +There are a couple different approaches being used to tackle this, with |
| 41 | +different levels of interaction required from the user, but they all require a |
| 42 | +significant ammount of effort. This is due to the lack of standardized |
| 43 | +cross-compilation infrastructure on the Python packaging ecosystem, which itself |
| 44 | +stems from the complexity of cross-builds, making it a huge undertaking. |
| 45 | + |
| 46 | + |
| 47 | +Upstream support |
| 48 | +---------------- |
| 49 | + |
| 50 | +Some major projects like CPython, setuptools, etc. provide some support to help |
| 51 | +with cross-compilation, but it's unofficial and at a best-effort basis. For |
| 52 | +example, the ``sysconfig`` module allows overwriting the data module name via |
| 53 | +the ``_PYTHON_SYSCONFIGDATA_NAME`` environment variable, something that is |
| 54 | +required for cross-builds, and setuptools `accepts patches`__ [1]_ to tweak/fix |
| 55 | +its logic to be compatible with popular |
| 56 | +:ref:`"environment faking" <approach-target-environment>` workflows [2]_. |
| 57 | + |
| 58 | +The lack of first-party support in upstream projects leads to cross-compilation |
| 59 | +being fragile and requiring a significant effort from users, however, the lack |
| 60 | +of standardization makes it harder for upstreams to improve support, even if |
| 61 | +they wanted, as there's no clarity on how this feature should be provided. |
| 62 | + |
| 63 | +.. [1] At the time of writing (Jun 2023), setuptools' compiler interface code, |
| 64 | + the compoment that most of affects cross-compilation, is developed on the |
| 65 | + `pypa/distutils`__ repository, which gets periodically synced to the |
| 66 | + setuptools repository. |
| 67 | +
|
| 68 | +.. [2] We specifically mention *popular* workflows, because since this is not |
| 69 | + standardized, there isn't a single unified approach. Though, many of the |
| 70 | + most popular implementations (crossenv_, conda-forge_'s build system, |
| 71 | + etc.) work similarly, and this is what we are refering to here. For |
| 72 | + clarity, the implementations we are refering to here could be described |
| 73 | + as *crossenv-style*. |
| 74 | +
|
| 75 | +.. __: https://github.com/pypa/distutils/pulls?q=cross |
| 76 | +.. __: https://github.com/pypa/distutils |
| 77 | + |
| 78 | +Projects with decent cross-build support |
| 79 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 80 | + |
| 81 | +It seems relevant to point out that there are a few modern Python package |
| 82 | +build-backends with, at least, decent cross-compilation support, those being |
| 83 | +scikit-build__ and meson-python__. Both these projects integrate external mature |
| 84 | +build-systems into Python packaging — CMake__ and Meson__, respectively — so |
| 85 | +cross-build support is inherited from them. |
| 86 | + |
| 87 | +.. __: https://github.com/scikit-build/scikit-build |
| 88 | +.. __: https://github.com/mesonbuild/meson-python |
| 89 | +.. __: https://cmake.org/ |
| 90 | +.. __: https://mesonbuild.com/ |
| 91 | + |
| 92 | + |
| 93 | +Downstream approaches |
| 94 | +--------------------- |
| 95 | + |
| 96 | +Cross-compilation approaches fall in a spectrum that goes from, by design, |
| 97 | +requiring extensive user interaction to (ideally) almost none. Usually, they'll |
| 98 | +be based on one of two main strategies, using a |
| 99 | +:ref:`cross-build environment <approach-cross-environment>`, or |
| 100 | +:ref:`faking the target environment <approach-target-environment>`. |
| 101 | + |
| 102 | +.. _approach-cross-environment: |
| 103 | + |
| 104 | +Cross-build environment |
| 105 | +~~~~~~~~~~~~~~~~~~~~~~~ |
| 106 | + |
| 107 | +This consists of running the Python interpreter normally and utilizing the |
| 108 | +cross-build provided by the projects' build-system. However, as we saw above, |
| 109 | +upstream support is pretty lacking, so this approach only works for a small-ish |
| 110 | +set of projects. When this fails, the usual strategy is to patch the |
| 111 | +build-system code to build use the correct toolchain, system details, etc. [3]_. |
| 112 | + |
| 113 | +Since this approach often requires package-specific patching, it requires a lot |
| 114 | +of user interaction. |
| 115 | + |
| 116 | +.. admonition:: Examples |
| 117 | + :class: note |
| 118 | + |
| 119 | + :ref:`python-for-android`, :ref:`kivy-ios`, etc. |
| 120 | + |
| 121 | +.. [3] The scope of the build-system patching varies between users and |
| 122 | + usually depends on the their goal — some (eg. Linux distributions) may |
| 123 | + patch the build-system to support cross-builds, while others might |
| 124 | + hardcode compiler paths and system information in the build-system, to |
| 125 | + simply make the build work. |
| 126 | +
|
| 127 | +.. _approach-target-environment: |
| 128 | + |
| 129 | +Faking the target environment |
| 130 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 131 | + |
| 132 | +Aiming to drop the requirement for user input, a popular approach is trying to |
| 133 | +fake the target environment. It generally consists of monkeypatching the Python |
| 134 | +interpreter to get it to mimick the interpreter on the target system, which |
| 135 | +constitutes of changing many of the `sys` module attributes, the `sysconfig` |
| 136 | +data, etc. Using this strategy, build-backends do not need to have any |
| 137 | +cross-build support, and should just work without any code changes. |
| 138 | + |
| 139 | +Unfortunately, though, it isn't possible to truly fake the target environment. |
| 140 | +There are many reasons for this, one of the main ones being that it breaks code |
| 141 | +that actually needs to introspect the running interpreter. As a result, |
| 142 | +monkeypatching Python to look like target is very tricky — to achieve the less |
| 143 | +ammount of breakage, we can only patch certain aspects of the interpreter. |
| 144 | +Consequently, build-backends may need some code changes, but these are generally |
| 145 | +much smaller than the previous approach. This is an inherent limitation of the |
| 146 | +technique, meaning this strategy still requires some user interaction. |
| 147 | + |
| 148 | +Nonetheless, this strategy still works out-of-the-box with significantly more |
| 149 | +projects than the approach above, and requires much less effort in these cases. |
| 150 | +It is sucessfull in decreasing the ammount of user interaction needed, even |
| 151 | +though it doesn't succeed in being generic. |
| 152 | + |
| 153 | +.. admonition:: Examples |
| 154 | + :class: note |
| 155 | + |
| 156 | + :ref:`crossenv`, :ref:`conda-forge`, etc. |
| 157 | + |
| 158 | + |
| 159 | +Case studies |
| 160 | +============ |
| 161 | + |
| 162 | + |
| 163 | +.. _crossenv: |
| 164 | + |
| 165 | +crossenv |
| 166 | +-------- |
| 167 | + |
| 168 | +:Description: Virtual Environments for Cross-Compiling Python Extension Modules. |
| 169 | +:URL: https://github.com/benfogle/crossenv |
| 170 | + |
| 171 | +``crossenv`` is a tool to create a virtual environment with a monkeypatched |
| 172 | +Python installation that tries to emulate the target machine in certain |
| 173 | +scenarios. More about this approach can be found in the |
| 174 | +:ref:`approach-target-environment` section. |
| 175 | + |
| 176 | + |
| 177 | +.. _conda-forge: |
| 178 | + |
| 179 | +conda-forge |
| 180 | +----------- |
| 181 | + |
| 182 | +:Description: A community-led collection of recipes, build infrastructure and distributions for the conda package manager. |
| 183 | +:URL: https://conda-forge.org/ |
| 184 | + |
| 185 | +XXX: Jaime will write a quick summary once the PEP draft is public. |
| 186 | + |
| 187 | +XXX |
| 188 | +Uses a modified crossenv. |
| 189 | + |
| 190 | + |
| 191 | +Yocto Project |
| 192 | +------------- |
| 193 | + |
| 194 | +:Description: The Yocto Project is an open source collaboration project that helps developers create custom Linux-based systems regardless of the hardware architecture. |
| 195 | +:URL: https://www.yoctoproject.org/ |
| 196 | + |
| 197 | +XXX: Sent email to the mailing list. |
| 198 | + |
| 199 | +TODO |
| 200 | + |
| 201 | + |
| 202 | +Buildroot |
| 203 | +--------- |
| 204 | + |
| 205 | +:Description: Buildroot is a simple, efficient and easy-to-use tool to generate embedded Linux systems through cross-compilation. |
| 206 | +:URL: https://buildroot.org/ |
| 207 | + |
| 208 | +TODO |
| 209 | + |
| 210 | + |
| 211 | +Pyodide |
| 212 | +------- |
| 213 | + |
| 214 | +:Description: Pyodide is a Python distribution for the browser and Node.js based on WebAssembly. |
| 215 | +:URL: https://pyodide.org/en/stable/ |
| 216 | + |
| 217 | +XXX: Hood should review/expand this section. |
| 218 | + |
| 219 | +``Pyodide`` is a provides a Python distribution compied to WebAssembly__ |
| 220 | +using the Emscripten__ toolchain. |
| 221 | + |
| 222 | +It patches several aspects of the CPython installation and some external |
| 223 | +components. A custom package manager — micropip__ — supporting both Pure and |
| 224 | +wasm32/Emscripten wheels, is also provided as a part of the distribution. On top |
| 225 | +of this, a repo with a `selected set of 3rd party packages`__ is also provided |
| 226 | +and enabled by default. |
| 227 | + |
| 228 | +.. __: https://webassembly.org/ |
| 229 | +.. __: https://emscripten.org/ |
| 230 | +.. __: https://micropip.pyodide.org/ |
| 231 | +.. __: https://pyodide.org/en/stable/usage/packages-in-pyodide.html |
| 232 | + |
| 233 | + |
| 234 | +Beeware |
| 235 | +------- |
| 236 | + |
| 237 | +:Description: BeeWare allows you to write your app in Python and release it on multiple platforms. |
| 238 | +:URL: https://beeware.org/ |
| 239 | + |
| 240 | +TODO |
| 241 | + |
| 242 | + |
| 243 | +.. _python-for-android: |
| 244 | + |
| 245 | +python-for-android |
| 246 | +------------------ |
| 247 | + |
| 248 | +:Description: Turn your Python application into an Android APK. |
| 249 | +:URL: https://github.com/kivy/python-for-android |
| 250 | + |
| 251 | +resource https://github.com/Android-for-Python/Android-for-Python-Users |
| 252 | + |
| 253 | +``python-for-android`` is a tool to package Python apps on Android. It creates a |
| 254 | +Python distribution with your app and its dependencies. |
| 255 | + |
| 256 | +Pure-Python dependencies are handled automatically and in a generic way, but |
| 257 | +native dependencies need recipes__. A set of recipes for |
| 258 | +`popular dependencies`__ is provided, but users need to provide their own |
| 259 | +recipes for any other native dependencies. |
| 260 | + |
| 261 | +.. __: https://python-for-android.readthedocs.io/en/latest/recipes/ |
| 262 | +.. __: https://github.com/kivy/python-for-android/tree/develop/pythonforandroid/recipes |
| 263 | + |
| 264 | + |
| 265 | +.. _kivy-ios: |
| 266 | + |
| 267 | +kivy-ios |
| 268 | +-------- |
| 269 | + |
| 270 | +:Description: Toolchain for compiling Python / Kivy / other libraries for iOS. |
| 271 | +:URL: https://github.com/kivy/kivy-ios |
| 272 | + |
| 273 | +``kivy-ios`` is a tool to package Python apps on iOS. It provides a toolchain to |
| 274 | +build a Python distribution with your app and its dependencies, as well as a CLI |
| 275 | +to create and manage Xcode projects that integrate with the toolchain. |
| 276 | + |
| 277 | +It uses the same approach as :ref:`python-for-android` (also maintained by the |
| 278 | +`Kivy project`__) for app dependencies — pure-Python dependencies are handled |
| 279 | +automatically, but native dependencies need recipes__, and the project provides |
| 280 | +recipes for `popular dependencies`__. |
| 281 | + |
| 282 | +.. __: https://kivy.org |
| 283 | +.. __: https://python-for-android.readthedocs.io/en/latest/recipes/ |
| 284 | +.. __: https://github.com/kivy/kivy-ios/tree/master/kivy_ios/recipes |
| 285 | + |
| 286 | + |
| 287 | +AidLearning |
| 288 | +----------- |
| 289 | + |
| 290 | +:Description: AI, Android, Linux, ARM: AI application development platform based on Android+Linux integrated ecology. |
| 291 | +:URL: https://github.com/aidlearning/AidLearning-FrameWork |
| 292 | + |
| 293 | +TODO |
| 294 | + |
| 295 | + |
| 296 | +QPython |
| 297 | +------- |
| 298 | + |
| 299 | +:Description: QPython is the Python engine for android. |
| 300 | +:URL: https://github.com/qpython-android/qpython |
| 301 | + |
| 302 | +TODO |
| 303 | + |
| 304 | + |
| 305 | +pyqtdeploy |
| 306 | +---------- |
| 307 | + |
| 308 | +:Description: pyqtdeploy is a tool for deploying PyQt applications. |
| 309 | +:URL: https://www.riverbankcomputing.com/software/pyqtdeploy/ |
| 310 | + |
| 311 | +contact https://www.riverbankcomputing.com/pipermail/pyqt/2023-May/thread.html |
| 312 | +contacted Phil, the maintainer |
| 313 | + |
| 314 | +TODO |
| 315 | + |
| 316 | + |
| 317 | +Chaquopy |
| 318 | +-------- |
| 319 | + |
| 320 | +:Description: Chaquopy provides everything you need to include Python components in an Android app. |
| 321 | +:URL: https://chaquo.com/chaquopy/ |
| 322 | + |
| 323 | +TODO |
| 324 | + |
| 325 | + |
| 326 | +EDK II |
| 327 | +------ |
| 328 | + |
| 329 | +:Description: EDK II is a modern, feature-rich, cross-platform firmware development environment for the UEFI and PI specifications. |
| 330 | +:URL: https://github.com/tianocore/edk2-libc/tree/master/AppPkg/Applications/Python |
| 331 | + |
| 332 | +TODO |
| 333 | + |
| 334 | + |
| 335 | +ActivePython |
| 336 | +------------ |
| 337 | + |
| 338 | +:Description: Commercial-grade, quality-assured Python distribution focusing on easy installation and cross-platform compatibility on Windows, Linux, Mac OS X, Solaris, HP-UX and AIX. |
| 339 | +:URL: https://www.activestate.com/products/python/ |
| 340 | + |
| 341 | +TODO |
| 342 | + |
| 343 | + |
| 344 | +Termux |
| 345 | +------ |
| 346 | + |
| 347 | +:Description: Termux is an Android terminal emulator and Linux environment app that works directly with no rooting or setup required. |
| 348 | +:URL: https://termux.dev/en/ |
| 349 | + |
| 350 | +TODO |
0 commit comments