Skip to content

Commit 8faa7eb

Browse files
committed
PEP 9999: add "Cross-compiling Python packages" PEP draft
Signed-off-by: Filipe Laíns <lains@riseup.net>
1 parent 1b0666e commit 8faa7eb

File tree

1 file changed

+350
-0
lines changed

1 file changed

+350
-0
lines changed

pep-9999.rst

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
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

Comments
 (0)