From e90133a90fa4d026b365202f0d54c81e2a634939 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sat, 29 Jun 2024 18:07:48 +0200 Subject: [PATCH] Updated recipes --- recipes/numpy/__init__.py | 75 +++++++++++++++++++ .../add_libm_explicitly_to_build.patch | 20 +++++ recipes/numpy/patches/ranlib.patch | 11 +++ .../numpy/patches/remove-default-paths.patch | 28 +++++++ recipes/pycodec2/__init__.py | 2 +- sbapp/buildozer.spec | 2 +- 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 recipes/numpy/__init__.py create mode 100644 recipes/numpy/patches/add_libm_explicitly_to_build.patch create mode 100644 recipes/numpy/patches/ranlib.patch create mode 100644 recipes/numpy/patches/remove-default-paths.patch diff --git a/recipes/numpy/__init__.py b/recipes/numpy/__init__.py new file mode 100644 index 0000000..55a0279 --- /dev/null +++ b/recipes/numpy/__init__.py @@ -0,0 +1,75 @@ +from pythonforandroid.recipe import CompiledComponentsPythonRecipe +from pythonforandroid.logger import shprint, info +from pythonforandroid.util import current_directory +from multiprocessing import cpu_count +from os.path import join +import glob +import sh +import shutil + + +class NumpyRecipe(CompiledComponentsPythonRecipe): + + version = '1.22.3' + url = 'https://pypi.python.org/packages/source/n/numpy/numpy-{version}.zip' + site_packages_name = 'numpy' + depends = ['setuptools', 'cython'] + install_in_hostpython = True + call_hostpython_via_targetpython = False + + patches = [ + join("patches", "remove-default-paths.patch"), + join("patches", "add_libm_explicitly_to_build.patch"), + join("patches", "ranlib.patch"), + ] + + def get_recipe_env(self, arch=None, with_flags_in_cc=True): + env = super().get_recipe_env(arch, with_flags_in_cc) + + # _PYTHON_HOST_PLATFORM declares that we're cross-compiling + # and avoids issues when building on macOS for Android targets. + env["_PYTHON_HOST_PLATFORM"] = arch.command_prefix + + # NPY_DISABLE_SVML=1 allows numpy to build for non-AVX512 CPUs + # See: https://github.com/numpy/numpy/issues/21196 + env["NPY_DISABLE_SVML"] = "1" + + return env + + def _build_compiled_components(self, arch): + info('Building compiled components in {}'.format(self.name)) + + env = self.get_recipe_env(arch) + with current_directory(self.get_build_dir(arch.arch)): + hostpython = sh.Command(self.hostpython_location) + shprint(hostpython, 'setup.py', self.build_cmd, '-v', + _env=env, *self.setup_extra_args) + build_dir = glob.glob('build/lib.*')[0] + shprint(sh.find, build_dir, '-name', '"*.o"', '-exec', + env['STRIP'], '{}', ';', _env=env) + + def _rebuild_compiled_components(self, arch, env): + info('Rebuilding compiled components in {}'.format(self.name)) + + hostpython = sh.Command(self.real_hostpython_location) + shprint(hostpython, 'setup.py', 'clean', '--all', '--force', _env=env) + shprint(hostpython, 'setup.py', self.build_cmd, '-v', _env=env, + *self.setup_extra_args) + + def build_compiled_components(self, arch): + self.setup_extra_args = ['-j', str(cpu_count())] + self._build_compiled_components(arch) + self.setup_extra_args = [] + + def rebuild_compiled_components(self, arch, env): + self.setup_extra_args = ['-j', str(cpu_count())] + self._rebuild_compiled_components(arch, env) + self.setup_extra_args = [] + + def get_hostrecipe_env(self, arch): + env = super().get_hostrecipe_env(arch) + env['RANLIB'] = shutil.which('ranlib') + return env + + +recipe = NumpyRecipe() diff --git a/recipes/numpy/patches/add_libm_explicitly_to_build.patch b/recipes/numpy/patches/add_libm_explicitly_to_build.patch new file mode 100644 index 0000000..f9ba9e9 --- /dev/null +++ b/recipes/numpy/patches/add_libm_explicitly_to_build.patch @@ -0,0 +1,20 @@ +diff --git a/numpy/linalg/setup.py b/numpy/linalg/setup.py +index 66c07c9..d34bd93 100644 +--- a/numpy/linalg/setup.py ++++ b/numpy/linalg/setup.py +@@ -46,6 +46,7 @@ def configuration(parent_package='', top_path=None): + sources=['lapack_litemodule.c', get_lapack_lite_sources], + depends=['lapack_lite/f2c.h'], + extra_info=lapack_info, ++ libraries=['m'], + ) + + # umath_linalg module +@@ -54,7 +54,7 @@ def configuration(parent_package='', top_path=None): + sources=['umath_linalg.c.src', get_lapack_lite_sources], + depends=['lapack_lite/f2c.h'], + extra_info=lapack_info, +- libraries=['npymath'], ++ libraries=['npymath', 'm'], + ) + return config diff --git a/recipes/numpy/patches/ranlib.patch b/recipes/numpy/patches/ranlib.patch new file mode 100644 index 0000000..c0b5dad --- /dev/null +++ b/recipes/numpy/patches/ranlib.patch @@ -0,0 +1,11 @@ +diff -Naur numpy.orig/numpy/distutils/unixccompiler.py numpy/numpy/distutils/unixccompiler.py +--- numpy.orig/numpy/distutils/unixccompiler.py 2022-05-28 10:22:10.000000000 +0200 ++++ numpy/numpy/distutils/unixccompiler.py 2022-05-28 10:22:24.000000000 +0200 +@@ -124,6 +124,7 @@ + # platform intelligence here to skip ranlib if it's not + # needed -- or maybe Python's configure script took care of + # it for us, hence the check for leading colon. ++ self.ranlib = [os.environ.get('RANLIB')] + if self.ranlib: + display = '%s:@ %s' % (os.path.basename(self.ranlib[0]), + output_filename) diff --git a/recipes/numpy/patches/remove-default-paths.patch b/recipes/numpy/patches/remove-default-paths.patch new file mode 100644 index 0000000..3581f0f --- /dev/null +++ b/recipes/numpy/patches/remove-default-paths.patch @@ -0,0 +1,28 @@ +diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py +index fc7018a..7b514bc 100644 +--- a/numpy/distutils/system_info.py ++++ b/numpy/distutils/system_info.py +@@ -340,10 +340,10 @@ if os.path.join(sys.prefix, 'lib') not in default_lib_dirs: + default_include_dirs.append(os.path.join(sys.prefix, 'include')) + default_src_dirs.append(os.path.join(sys.prefix, 'src')) + +-default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)] +-default_runtime_dirs = [_m for _m in default_runtime_dirs if os.path.isdir(_m)] +-default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)] +-default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)] ++default_lib_dirs = [] #[_m for _m in default_lib_dirs if os.path.isdir(_m)] ++default_runtime_dirs =[] # [_m for _m in default_runtime_dirs if os.path.isdir(_m)] ++default_include_dirs =[] # [_m for _m in default_include_dirs if os.path.isdir(_m)] ++default_src_dirs =[] # [_m for _m in default_src_dirs if os.path.isdir(_m)] + + so_ext = get_shared_lib_extension() + +@@ -814,7 +814,7 @@ class system_info(object): + path = self.get_paths(self.section, key) + if path == ['']: + path = [] +- return path ++ return [] + + def get_include_dirs(self, key='include_dirs'): + return self.get_paths(self.section, key) diff --git a/recipes/pycodec2/__init__.py b/recipes/pycodec2/__init__.py index 1e4ace9..df11c3e 100644 --- a/recipes/pycodec2/__init__.py +++ b/recipes/pycodec2/__init__.py @@ -7,7 +7,7 @@ import sh class PyCodec2Recipe(CythonRecipe): url = "https://github.com/markqvist/pycodec2/archive/refs/heads/main.zip" # src_filename = "../../../pycodec2" - depends = ["setuptools", "numpy==1.26.4", "Cython", "codec2"] + depends = ["setuptools", "numpy", "Cython", "codec2"] call_hostpython_via_targetpython = False def get_recipe_env(self, arch, with_flags_in_cc=True): diff --git a/sbapp/buildozer.spec b/sbapp/buildozer.spec index ea04481..8b41ecb 100644 --- a/sbapp/buildozer.spec +++ b/sbapp/buildozer.spec @@ -12,7 +12,7 @@ version.regex = __version__ = ['"](.*)['"] version.filename = %(source.dir)s/main.py android.numeric_version = 20240629 -requirements = kivy==2.3.0,libbz2,pillow==10.2.0,qrcode==7.3.1,usb4a,usbserial4a,libwebp,libogg,libopus,opusfile,numpy==1.26.4,cryptography,ffpyplayer,codec2,pycodec2,sh +requirements = kivy==2.3.0,libbz2,pillow==10.2.0,qrcode==7.3.1,usb4a,usbserial4a,libwebp,libogg,libopus,opusfile,numpy,cryptography,ffpyplayer,codec2,pycodec2,sh android.gradle_dependencies = com.android.support:support-compat:28.0.0 #android.enable_androidx = True