Skip to content

Commit 83e74ca

Browse files
authored
Add support for Python 3.11 and make it the default while building hostpython3 and python3 (#2850)
* python: update to 3.11.5 * scipy: update to 1.11.3 * add `pybind11` to `ci/constants.py` in BROKEN_RECIPES_PYTHON3
1 parent 17bf532 commit 83e74ca

File tree

9 files changed

+1158
-16
lines changed

9 files changed

+1158
-16
lines changed

ci/constants.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class TargetPython(Enum):
3939
'boost',
4040
# libtorrent gives errors (requires boost. Also, see issue #2809, to start with)
4141
'libtorrent',
42-
42+
# pybind11 build fails on macos
43+
'pybind11',
4344
])
4445

4546
BROKEN_RECIPES = {

pythonforandroid/bootstraps/common/build/src/main/java/org/kivy/android/PythonUtil.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ protected static ArrayList<String> getLibraries(File libsDir) {
5555
libsList.add("python3.8");
5656
libsList.add("python3.9");
5757
libsList.add("python3.10");
58+
libsList.add("python3.11");
5859
libsList.add("main");
5960
return libsList;
6061
}
@@ -74,7 +75,7 @@ public static void loadLibraries(File filesDir, File libsDir) {
7475
// load, and it has failed, give a more
7576
// general error
7677
Log.v(TAG, "Library loading error: " + e.getMessage());
77-
if (lib.startsWith("python3.10") && !foundPython) {
78+
if (lib.startsWith("python3.11") && !foundPython) {
7879
throw new RuntimeException("Could not load any libpythonXXX.so");
7980
} else if (lib.startsWith("python")) {
8081
continue;

pythonforandroid/recipes/cython/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
class CythonRecipe(CompiledComponentsPythonRecipe):
55

6-
version = '0.29.28'
6+
version = '0.29.36'
77
url = 'https://github.com/cython/cython/archive/{version}.tar.gz'
88
site_packages_name = 'cython'
99
depends = ['setuptools']

pythonforandroid/recipes/hostpython3/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class HostPython3Recipe(Recipe):
3535
:class:`~pythonforandroid.python.HostPythonRecipe`
3636
'''
3737

38-
version = '3.10.10'
38+
version = '3.11.5'
3939
name = 'hostpython3'
4040

4141
build_subdir = 'native-build'

pythonforandroid/recipes/pybind11/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
class Pybind11Recipe(PythonRecipe):
66

7-
version = '2.9.0'
7+
version = '2.11.1'
88
url = 'https://github.com/pybind/pybind11/archive/refs/tags/v{version}.zip'
99
depends = ['setuptools']
1010
call_hostpython_via_targetpython = False

pythonforandroid/recipes/python3/__init__.py

+20-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import sh
33
import subprocess
44

5-
from multiprocessing import cpu_count
65
from os import environ, utime
76
from os.path import dirname, exists, join
87
from pathlib import Path
@@ -56,7 +55,7 @@ class Python3Recipe(TargetPythonRecipe):
5655
:class:`~pythonforandroid.python.GuestPythonRecipe`
5756
'''
5857

59-
version = '3.10.10'
58+
version = '3.11.5'
6059
url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'
6160
name = 'python3'
6261

@@ -71,15 +70,17 @@ class Python3Recipe(TargetPythonRecipe):
7170
# Python 3.8.1 & 3.9.X
7271
('patches/py3.8.1.patch', version_starts_with("3.8")),
7372
('patches/py3.8.1.patch', version_starts_with("3.9")),
74-
('patches/py3.8.1.patch', version_starts_with("3.10"))
73+
('patches/py3.8.1.patch', version_starts_with("3.10")),
74+
('patches/cpython-311-ctypes-find-library.patch', version_starts_with("3.11")),
7575
]
7676

7777
if shutil.which('lld') is not None:
78-
patches = patches + [
78+
patches += [
7979
("patches/py3.7.1_fix_cortex_a8.patch", version_starts_with("3.7")),
8080
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.8")),
8181
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.9")),
82-
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.10"))
82+
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.10")),
83+
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.11")),
8384
]
8485

8586
depends = ['hostpython3', 'sqlite3', 'openssl', 'libffi']
@@ -101,7 +102,12 @@ class Python3Recipe(TargetPythonRecipe):
101102
'ac_cv_header_sys_eventfd_h=no',
102103
'--prefix={prefix}',
103104
'--exec-prefix={exec_prefix}',
104-
'--enable-loadable-sqlite-extensions')
105+
'--enable-loadable-sqlite-extensions'
106+
)
107+
108+
if version_starts_with("3.11"):
109+
configure_args += ('--with-build-python={python_host_bin}',)
110+
105111
'''The configure arguments needed to build the python recipe. Those are
106112
used in method :meth:`build_arch` (if not overwritten like python3's
107113
recipe does).
@@ -323,12 +329,19 @@ def build_arch(self, arch):
323329
*(' '.join(self.configure_args).format(
324330
android_host=env['HOSTARCH'],
325331
android_build=android_build,
332+
python_host_bin=join(self.get_recipe(
333+
'host' + self.name, self.ctx
334+
).get_path_to_python(), "python3"),
326335
prefix=sys_prefix,
327336
exec_prefix=sys_exec_prefix)).split(' '),
328337
_env=env)
329338

339+
# Python build does not seem to play well with make -j option from Python 3.11 and onwards
340+
# Before losing some time, please check issue
341+
# https://github.com/python/cpython/issues/101295 , as the root cause looks similar
330342
shprint(
331-
sh.make, 'all', '-j', str(cpu_count()),
343+
sh.make,
344+
'all',
332345
'INSTSONAME={lib_name}'.format(lib_name=self._libpython),
333346
_env=env
334347
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--- Python-3.11.5/Lib/ctypes/util.py 2023-08-24 17:39:18.000000000 +0530
2+
+++ Python-3.11.5.mod/Lib/ctypes/util.py 2023-11-18 22:12:17.356160615 +0530
3+
@@ -4,7 +4,15 @@
4+
import sys
5+
6+
# find_library(name) returns the pathname of a library, or None.
7+
-if os.name == "nt":
8+
+
9+
+# This patch overrides the find_library to look in the right places on
10+
+# Android
11+
+if True:
12+
+ from android._ctypes_library_finder import find_library as _find_lib
13+
+ def find_library(name):
14+
+ return _find_lib(name)
15+
+
16+
+elif os.name == "nt":
17+
18+
def _get_build_version():
19+
"""Return the version of MSVC that was used to build Python.

pythonforandroid/recipes/scipy/__init__.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
from pythonforandroid.recipe import CompiledComponentsPythonRecipe, Recipe
21
from multiprocessing import cpu_count
32
from os.path import join
43
from os import environ
5-
from pythonforandroid.util import build_platform
4+
import sh
5+
from pythonforandroid.logger import shprint
6+
from pythonforandroid.recipe import CompiledComponentsPythonRecipe, Recipe
7+
from pythonforandroid.util import build_platform, current_directory
68

79

810
def arch_to_toolchain(arch):
@@ -13,12 +15,14 @@ def arch_to_toolchain(arch):
1315

1416
class ScipyRecipe(CompiledComponentsPythonRecipe):
1517

16-
version = '1.8.1'
17-
url = f'https://github.com/scipy/scipy/releases/download/v{version}/scipy-{version}.zip'
18+
version = 'maintenance/1.11.x'
19+
url = 'git+https://github.com/scipy/scipy.git'
20+
git_commit = 'b430bf54b5064465983813e2cfef3fcb86c3df07' # version 1.11.3
1821
site_packages_name = 'scipy'
1922
depends = ['setuptools', 'cython', 'numpy', 'lapack', 'pybind11']
2023
call_hostpython_via_targetpython = False
2124
need_stl_shared = True
25+
patches = ["setup.py.patch"]
2226

2327
def build_compiled_components(self, arch):
2428
self.setup_extra_args = ['-j', str(cpu_count())]
@@ -30,6 +34,12 @@ def rebuild_compiled_components(self, arch, env):
3034
super().rebuild_compiled_components(arch, env)
3135
self.setup_extra_args = []
3236

37+
def download_file(self, url, target, cwd=None):
38+
super().download_file(url, target, cwd=cwd)
39+
with current_directory(target):
40+
shprint(sh.git, 'fetch', '--unshallow')
41+
shprint(sh.git, 'checkout', self.git_commit)
42+
3343
def get_recipe_env(self, arch):
3444
env = super().get_recipe_env(arch)
3545
arch_env = arch.get_env()

0 commit comments

Comments
 (0)