@@ -79,3 +79,154 @@ Release checklist
79
79
- [ ] `armeabi-v7a `
80
80
- [ ] `arm64-v8a `
81
81
- [ ] Check that the version number is correct
82
+
83
+
84
+
85
+ How python-for-android uses `pip `
86
+ ---------------------------------
87
+
88
+ *Last update: July 2019 *
89
+
90
+ This section is meant to provide a quick summary how
91
+ p4a (=python-for-android) uses pip and python packages in
92
+ its build process.
93
+ **It is written for a python
94
+ packagers point of view, not for regular end users or
95
+ contributors, ** to assist with making pip developers and
96
+ other packaging experts aware of p4a's packaging needs.
97
+
98
+ Please note this section just attempts to neutrally list the
99
+ current mechanisms, so some of this isn't necessarily meant
100
+ to stay but just how things work inside p4a in
101
+ this very moment.
102
+
103
+
104
+ Basic concepts
105
+ ~~~~~~~~~~~~~~
106
+
107
+ *(This part repeats other parts of the docs, for the sake of
108
+ making this a more independent read) *
109
+
110
+ p4a builds & packages a python application for use on Android.
111
+ It does this by providing a Java wrapper, and for graphical applications
112
+ an SDL2-based wrapper which can be used with the kivy UI toolkit if
113
+ desired (or alternatively just plain PySDL2). Any such python application
114
+ will of course have further library dependencies to do its work.
115
+
116
+ p4a supports two types of package dependencies for a project:
117
+
118
+ **Recipe: ** install script in custom p4a format. Can either install
119
+ C/C++ or other things that cannot be pulled in via pip, or things
120
+ that can be installed via pip but break on android by default.
121
+ These are maintained primarily inside the p4a source tree by p4a
122
+ contributors and interested folks.
123
+
124
+ **Python package: ** any random pip python package can be directly
125
+ installed if it doesn't need adjustments to work for Android.
126
+
127
+ p4a will map any dependency to an internal recipe if present, and
128
+ otherwise use pip to obtain it regularly from whatever external source.
129
+
130
+
131
+ Install process regarding packages
132
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133
+
134
+ The install/build process of a p4a project, as triggered by the
135
+ `p4a apk ` command, roughly works as follows in regards to python
136
+ packages:
137
+
138
+ 1. The user has specified a project folder to install. This is either
139
+ just a folder with python scripts and a `main.py `, or it may
140
+ also have a `pyproject.toml ` for a more standardized install.
141
+
142
+ 2. Dependencies are collected: they can be either specified via
143
+ ``--requirements `` as a list of names or pip-style URLs, or p4a
144
+ can optionally scan them from a project folder via the
145
+ pep517 library (if there is a `pyproject.toml ` or `setup.py `).
146
+
147
+ 3. The collected dependencies are mapped to p4a's recipes if any are
148
+ available for them, otherwise they're kept around as external
149
+ regular package references.
150
+
151
+ 4. All the dependencies mapped to recipes are built via p4a's internal
152
+ mechanisms to build these recipes. (This may or may not indirectly
153
+ use pip, depending on whether the recipe wraps a python package
154
+ or not and uses pip to install or not.)
155
+
156
+ 5. **If the user has specified to install the project in standardized
157
+ ways, ** then the `setup.py `/whatever build system
158
+ of the project will be run. This happens with cross compilation set up
159
+ (`CC `/`CFLAGS `/... set to use the
160
+ proper toolchain) and a custom site-packages location.
161
+ The actual comand is a simple `pip install . ` in the project folder
162
+ with some extra options: e.g. all dependencies that were already
163
+ installed by recipes will be pinned with a `-c ` constraints file
164
+ to make sure pip won't install them, and build isolation will be
165
+ disabled via ``--no-build-isolation `` so pip doesn't reinstall
166
+ recipe-packages on its own.
167
+
168
+ **If the user has not specified to use standardized build approaches **,
169
+ p4a will simply install all the remaining dependencies that weren't
170
+ mapped to recipes directly and just plain copy in the user project
171
+ without installing. Any `setup.py ` or `pyproject.toml ` of the user
172
+ project will then be ignored in this step.
173
+
174
+ 6. Google's gradle is invoked to package it all up into an `.apk `.
175
+
176
+
177
+ Overall process / package relevant notes for p4a
178
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179
+
180
+ Here are some common things worth knowing about python-for-android's
181
+ dealing with python packages:
182
+
183
+ - Packages will work fine without a recipe if they would also build
184
+ on Linux ARM, don't use any API not available in the NDK if they
185
+ use native code, and don't use any weird compiler flags the toolchain
186
+ doesn't like if they use native code. The package also needs to
187
+ work with cross compilation.
188
+
189
+ - There is currently no easy way for a package to know it is being
190
+ cross-compiled (at least that we know of) other than examining the
191
+ `CC ` compiler that was set, or that it is being cross-compiled for
192
+ Android specifically. If that breaks a package it currently needs
193
+ to be worked around with a recipe.
194
+
195
+ - If a package does **not ** work, p4a developers will often create a
196
+ recipe instead of getting upstream to fix it because p4a simply
197
+ is too niche.
198
+
199
+ - Most packages without native code will just work out of the box.
200
+ Many with native code tend not to, especially if complex, e.g. numpy.
201
+
202
+ - Anything mapped to a p4a recipe cannot be just reinstalled by pip,
203
+ specifically also not inside build isolation as a dependency.
204
+ (It *may * work if the patches of the recipe are just relevant
205
+ to fix runtime issues.)
206
+ Therefore as of now, the best way to deal with this limitation seems
207
+ to be to keep build isolation always off.
208
+
209
+
210
+ Ideas for the future regarding packaging
211
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212
+
213
+ - We in overall prefer to use the recipe mechanism less if we can.
214
+ In overall the recipes are just a collection of workarounds.
215
+ It may look quite hacky from the outside, since p4a
216
+ version pins recipe-wrapped packages usually to make the patches reliably
217
+ apply. This creates work for the recipes to be kept up-to-date, and
218
+ obviously this approach doesn't scale too well. However, it has ended
219
+ up as a quite practical interims solution until better ways are found.
220
+
221
+ - Obviously, it would be nice if packages could know they are being
222
+ cross-compiled, and for Android specifically. We aren't currently aware
223
+ of a good mechanism for that.
224
+
225
+ - If pip could actually run the recipes (instead of p4a wrapping pip and
226
+ doing so) then this might even allow build isolation to work - but
227
+ this might be too complex to get working. It might be more practical
228
+ to just gradually reduce the reliance on recipes instead and make
229
+ more packages work out of the box. This has been done e.g. with
230
+ improvements to the cross-compile environment being set up automatically,
231
+ and we're open for any ideas on how to improve this.
232
+
0 commit comments