From eb7be00ee0e57d470002dea2526bf62998d3f8bc Mon Sep 17 00:00:00 2001 From: Ansh Dadwal Date: Tue, 17 Jun 2025 18:24:21 +0530 Subject: [PATCH] `update`: numpy, pandas, sdl2 --- ci/makefiles/android.mk | 4 ++-- doc/source/quickstart.rst | 4 ++-- doc/source/testing_pull_requests.rst | 4 ++-- pythonforandroid/recipe.py | 8 ++++++++ pythonforandroid/recipes/numpy/__init__.py | 13 +++---------- pythonforandroid/recipes/pandas/__init__.py | 8 ++++---- pythonforandroid/recipes/python3/__init__.py | 11 +++++++++-- pythonforandroid/recipes/sdl2/__init__.py | 4 ++-- pythonforandroid/recommendations.py | 2 +- pythonforandroid/util.py | 15 ++++++++++----- testapps/on_device_unit_tests/setup.py | 6 +++--- testapps/setup_testapp_python3_sqlite_openssl.py | 2 +- testapps/setup_vispy.py | 2 +- testapps/testlauncherreboot_setup/sdl2.py | 2 +- tests/recipes/test_pandas.py | 2 +- tests/test_recipe.py | 2 ++ 16 files changed, 52 insertions(+), 37 deletions(-) diff --git a/ci/makefiles/android.mk b/ci/makefiles/android.mk index 2041a6ce76..fe05ad8698 100644 --- a/ci/makefiles/android.mk +++ b/ci/makefiles/android.mk @@ -1,12 +1,12 @@ # Downloads and installs the Android SDK depending on supplied platform: darwin or linux # Those android NDK/SDK variables can be override when running the file -ANDROID_NDK_VERSION ?= 25b +ANDROID_NDK_VERSION ?= 27c ANDROID_NDK_VERSION_LEGACY ?= 21e ANDROID_SDK_TOOLS_VERSION ?= 6514223 ANDROID_SDK_BUILD_TOOLS_VERSION ?= 29.0.3 ANDROID_HOME ?= $(HOME)/.android -ANDROID_API_LEVEL ?= 27 +ANDROID_API_LEVEL ?= 33 # per OS dictionary-like UNAME_S := $(shell uname -s) diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst index 61c33d6f16..589d1685ab 100644 --- a/doc/source/quickstart.rst +++ b/doc/source/quickstart.rst @@ -119,7 +119,7 @@ named ``tools``, and you will need to run extra commands to install the SDK packages needed. For Android NDK, note that modern releases will only work on a 64-bit -operating system. **The minimal, and recommended, NDK version to use is r25b:** +operating system. **The minimal, and recommended, NDK version to use is r27c:** - `Go to ndk downloads page `_ - Windows users should create a virtual machine with an GNU Linux os @@ -154,7 +154,7 @@ variables necessary for building on android:: # Adjust the paths! export ANDROIDSDK="$HOME/Documents/android-sdk-27" export ANDROIDNDK="$HOME/Documents/android-ndk-r23b" - export ANDROIDAPI="27" # Target API version of your application + export ANDROIDAPI="33" # Target API version of your application export NDKAPI="21" # Minimum supported API version of your application export ANDROIDNDKVER="r10e" # Version of the NDK you installed diff --git a/doc/source/testing_pull_requests.rst b/doc/source/testing_pull_requests.rst index f77748e336..f120755928 100644 --- a/doc/source/testing_pull_requests.rst +++ b/doc/source/testing_pull_requests.rst @@ -118,7 +118,7 @@ Using python-for-android commands directly from the pull request files --requirements=sdl2,pyjnius,kivy,python3,pycryptodome \ --ndk-dir=/media/DEVEL/Android/android-ndk-r20 \ --sdk-dir=/media/DEVEL/Android/android-sdk-linux \ - --android-api=27 \ + --android-api=33 \ --arch=arm64-v8a \ --permission=VIBRATE \ --debug @@ -175,7 +175,7 @@ Installing python-for-android using the github's branch of the pull request python3 setup.py apk \ --ndk-dir=/media/DEVEL/Android/android-ndk-r20 \ --sdk-dir=/media/DEVEL/Android/android-sdk-linux \ - --android-api=27 \ + --android-api=33 \ --arch=arm64-v8a \ --debug diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 44469aef2c..0ebe005d14 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -155,6 +155,11 @@ class Recipe(metaclass=RecipeMeta): starting from NDK r18 the `gnustl_shared` lib has been deprecated. ''' + min_ndk_api_support = 20 + ''' + Minimum ndk api recipe will support. + ''' + def get_stl_library(self, arch): return join( arch.ndk_lib_dir, @@ -375,6 +380,9 @@ def get_recipe_dir(self): # Public Recipe API to be subclassed if needed def download_if_necessary(self): + if self.ctx.ndk_api < self.min_ndk_api_support: + error(f"In order to build '{self.name}', you must set minimum ndk api (minapi) to `{self.min_ndk_api_support}`.\n") + exit(1) info_main('Downloading {}'.format(self.name)) user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower())) if user_dir is not None: diff --git a/pythonforandroid/recipes/numpy/__init__.py b/pythonforandroid/recipes/numpy/__init__.py index fb34c0c9f7..f85e44d4f5 100644 --- a/pythonforandroid/recipes/numpy/__init__.py +++ b/pythonforandroid/recipes/numpy/__init__.py @@ -1,5 +1,4 @@ from pythonforandroid.recipe import Recipe, MesonRecipe -from pythonforandroid.logger import error from os.path import join import shutil @@ -7,11 +6,12 @@ class NumpyRecipe(MesonRecipe): - version = 'v1.26.5' + version = 'v2.3.0' url = 'git+https://github.com/numpy/numpy' - hostpython_prerequisites = ["Cython>=3.0.6"] # meson does not detects venv's cython + hostpython_prerequisites = ["Cython>=3.0.6", "numpy"] # meson does not detects venv's cython extra_build_args = ['-Csetup-args=-Dblas=none', '-Csetup-args=-Dlapack=none'] need_stl_shared = True + min_ndk_api_support = 24 def get_recipe_meson_options(self, arch): options = super().get_recipe_meson_options(arch) @@ -36,13 +36,6 @@ def get_recipe_env(self, arch, **kwargs): "python3", self.ctx).get_build_dir(arch.arch), "android-build", "python") return env - def download_if_necessary(self): - # NumPy requires complex math functions which were added in api 24 - if self.ctx.ndk_api < 24: - error(NUMPY_NDK_MESSAGE) - exit(1) - super().download_if_necessary() - def build_arch(self, arch): super().build_arch(arch) self.restore_hostpython_prerequisites(["cython"]) diff --git a/pythonforandroid/recipes/pandas/__init__.py b/pythonforandroid/recipes/pandas/__init__.py index 3f56adef6c..6986e9efbe 100644 --- a/pythonforandroid/recipes/pandas/__init__.py +++ b/pythonforandroid/recipes/pandas/__init__.py @@ -3,10 +3,10 @@ class PandasRecipe(MesonRecipe): - version = 'v2.2.1' - url = 'git+https://github.com/pandas-dev/pandas' # noqa + version = 'v2.3.0' + url = 'git+https://github.com/pandas-dev/pandas' depends = ['numpy', 'libbz2', 'liblzma'] - hostpython_prerequisites = ["Cython~=3.0.5"] # meson does not detects venv's cython + hostpython_prerequisites = ["Cython<4.0.0a0", "versioneer", "numpy"] # meson does not detects venv's cython patches = ['fix_numpy_includes.patch'] python_depends = ['python-dateutil', 'pytz'] need_stl_shared = True @@ -17,7 +17,7 @@ def get_recipe_env(self, arch, **kwargs): # because we need some includes generated at numpy's compile time env['NUMPY_INCLUDES'] = join( - self.ctx.get_python_install_dir(arch.arch), "numpy/core/include", + self.ctx.get_python_install_dir(arch.arch), "numpy/_core/include", ) env["PYTHON_INCLUDE_DIR"] = self.ctx.python_recipe.include_root(arch) diff --git a/pythonforandroid/recipes/python3/__init__.py b/pythonforandroid/recipes/python3/__init__.py index 2334db6add..fef804d6d7 100644 --- a/pythonforandroid/recipes/python3/__init__.py +++ b/pythonforandroid/recipes/python3/__init__.py @@ -143,9 +143,15 @@ class Python3Recipe(TargetPythonRecipe): '__pycache__', 'tests' } - '''The directories from site packages dir that we don't want to be included + '''the directories from site packages dir that we don't want to be included in our python bundle.''' + site_packages_excluded_dir_exceptions = [ + 'numpy', + ] + '''Directories from `site_packages_dir_blacklist` will not be excluded + if the full path contains any of these exceptions.''' + site_packages_filen_blacklist = [ '*.py' ] @@ -419,7 +425,8 @@ def create_python_bundle(self, dirn, arch): with current_directory(self.ctx.get_python_install_dir(arch.arch)): filens = list(walk_valid_filens( '.', self.site_packages_dir_blacklist, - self.site_packages_filen_blacklist)) + self.site_packages_filen_blacklist, + excluded_dir_exceptions=self.site_packages_excluded_dir_exceptions)) info("Copy {} files into the site-packages".format(len(filens))) for filen in filens: info(" - copy {}".format(filen)) diff --git a/pythonforandroid/recipes/sdl2/__init__.py b/pythonforandroid/recipes/sdl2/__init__.py index cd0185c717..d1a5fdc8b3 100644 --- a/pythonforandroid/recipes/sdl2/__init__.py +++ b/pythonforandroid/recipes/sdl2/__init__.py @@ -6,9 +6,9 @@ class LibSDL2Recipe(BootstrapNDKRecipe): - version = "2.28.5" + version = "2.30.11" url = "https://github.com/libsdl-org/SDL/releases/download/release-{version}/SDL2-{version}.tar.gz" - md5sum = 'a344eb827a03045c9b399e99af4af13d' + md5sum = 'bea190b480f6df249db29eb3bacfe41e' conflicts = ['sdl3'] diff --git a/pythonforandroid/recommendations.py b/pythonforandroid/recommendations.py index 269a57fcf8..5584815d57 100644 --- a/pythonforandroid/recommendations.py +++ b/pythonforandroid/recommendations.py @@ -13,7 +13,7 @@ MAX_NDK_VERSION = 25 # DO NOT CHANGE LINE FORMAT: buildozer parses the existence of a RECOMMENDED_NDK_VERSION -RECOMMENDED_NDK_VERSION = "25b" +RECOMMENDED_NDK_VERSION = "27c" NDK_DOWNLOAD_URL = "https://developer.android.com/ndk/downloads/" diff --git a/pythonforandroid/util.py b/pythonforandroid/util.py index 13f38e6c0f..f9fbf61efc 100644 --- a/pythonforandroid/util.py +++ b/pythonforandroid/util.py @@ -48,7 +48,7 @@ def temp_directory(): temp_dir, Err_Fore.RESET))) -def walk_valid_filens(base_dir, invalid_dir_names, invalid_file_patterns): +def walk_valid_filens(base_dir, invalid_dir_names, invalid_file_patterns, excluded_dir_exceptions=[]): """Recursively walks all the files and directories in ``dirn``, ignoring directories that match any pattern in ``invalid_dirns`` and files that patch any pattern in ``invalid_filens``. @@ -60,15 +60,20 @@ def walk_valid_filens(base_dir, invalid_dir_names, invalid_file_patterns): File and directory paths are evaluated as full paths relative to ``dirn``. + If ``excluded_dir_exceptions`` is given, any directory path that contains + any of those strings will *not* exclude subdirectories matching + ``invalid_dir_names``. """ for dirn, subdirs, filens in walk(base_dir): + allow_invalid_dirs = any(ex in dirn for ex in excluded_dir_exceptions) # Remove invalid subdirs so that they will not be walked - for i in reversed(range(len(subdirs))): - subdir = subdirs[i] - if subdir in invalid_dir_names: - subdirs.pop(i) + if not allow_invalid_dirs: + for i in reversed(range(len(subdirs))): + subdir = subdirs[i] + if subdir in invalid_dir_names: + subdirs.pop(i) for filen in filens: for pattern in invalid_file_patterns: diff --git a/testapps/on_device_unit_tests/setup.py b/testapps/on_device_unit_tests/setup.py index a63ca8bcb7..48dae57e96 100644 --- a/testapps/on_device_unit_tests/setup.py +++ b/testapps/on_device_unit_tests/setup.py @@ -42,7 +42,7 @@ 'requirements': 'sqlite3,libffi,openssl,pyjnius,kivy,python3,requests,urllib3,' 'chardet,idna', - 'android-api': 27, + 'android-api': 33, 'ndk-api': 24, 'dist-name': 'bdist_unit_tests_app', 'arch': 'armeabi-v7a', @@ -56,7 +56,7 @@ 'requirements': 'sqlite3,libffi,openssl,pyjnius,kivy,python3,requests,urllib3,' 'chardet,idna', - 'android-api': 27, + 'android-api': 33, 'ndk-api': 24, 'dist-name': 'bdist_unit_tests_app', 'arch': 'armeabi-v7a', @@ -68,7 +68,7 @@ 'aar': { 'requirements' : 'python3', - 'android-api': 27, + 'android-api': 33, 'ndk-api': 24, 'dist-name': 'bdist_unit_tests_app', 'arch': 'arm64-v8a', diff --git a/testapps/setup_testapp_python3_sqlite_openssl.py b/testapps/setup_testapp_python3_sqlite_openssl.py index c6360679f1..6526743a44 100644 --- a/testapps/setup_testapp_python3_sqlite_openssl.py +++ b/testapps/setup_testapp_python3_sqlite_openssl.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages options = {'apk': {'requirements': 'requests,peewee,sdl2,pyjnius,kivy,python3', - 'android-api': 27, + 'android-api': 33, 'ndk-api': 21, 'bootstrap': 'sdl2', 'dist-name': 'bdisttest_python3_sqlite_openssl_googlendk', diff --git a/testapps/setup_vispy.py b/testapps/setup_vispy.py index f59d057b0b..81f4b5d7db 100644 --- a/testapps/setup_vispy.py +++ b/testapps/setup_vispy.py @@ -3,7 +3,7 @@ options = {'apk': {'debug': None, 'requirements': 'python3,vispy', 'blacklist-requirements': 'openssl,sqlite3', - 'android-api': 27, + 'android-api': 33, 'ndk-api': 21, 'bootstrap': 'empty', 'ndk-dir': '/home/asandy/android/android-ndk-r17c', diff --git a/testapps/testlauncherreboot_setup/sdl2.py b/testapps/testlauncherreboot_setup/sdl2.py index 8ea0d43c4c..de0aa5449a 100644 --- a/testapps/testlauncherreboot_setup/sdl2.py +++ b/testapps/testlauncherreboot_setup/sdl2.py @@ -54,7 +54,7 @@ # 'cymunk,lxml,pil,openssl,pyopenssl,' # 'twisted,audiostream,ffmpeg,numpy' - 'android-api': 27, + 'android-api': 33, 'ndk-api': 21, 'dist-name': 'bdisttest_python3launcher_sdl2_googlendk', 'name': 'TestLauncherPy3-sdl2', diff --git a/tests/recipes/test_pandas.py b/tests/recipes/test_pandas.py index b8366863fe..9a028d49b2 100644 --- a/tests/recipes/test_pandas.py +++ b/tests/recipes/test_pandas.py @@ -35,7 +35,7 @@ def test_get_recipe_env( self.ctx.recipe_build_order ) numpy_includes = join( - self.ctx.get_python_install_dir(self.arch.arch), "numpy/core/include", + self.ctx.get_python_install_dir(self.arch.arch), "numpy/_core/include", ) env = self.recipe.get_recipe_env(self.arch) self.assertIn(numpy_includes, env["NUMPY_INCLUDES"]) diff --git a/tests/test_recipe.py b/tests/test_recipe.py index b02a874e84..e2e0e9d826 100644 --- a/tests/test_recipe.py +++ b/tests/test_recipe.py @@ -93,6 +93,8 @@ def test_download_if_necessary(self): """ # download should happen as the environment variable is not set recipe = DummyRecipe() + recipe.ctx = Context() + recipe.ctx._ndk_api = 36 with mock.patch.object(Recipe, 'download') as m_download: recipe.download_if_necessary() assert m_download.call_args_list == [mock.call()]