Updated build recipes

This commit is contained in:
Mark Qvist 2025-10-28 02:22:25 +01:00
parent 846e7d7687
commit 6a133842db
32 changed files with 1154 additions and 1614 deletions

View file

@ -0,0 +1,37 @@
"""
Android Bluetooth Low Energy
"""
from pythonforandroid.recipe import PythonRecipe
from pythonforandroid.toolchain import current_directory, info, shprint
import sh
from os.path import join
class AbleRecipe(PythonRecipe):
name = 'able_recipe'
depends = ['python3', 'setuptools', 'android']
call_hostpython_via_targetpython = False
install_in_hostpython = True
def prepare_build_dir(self, arch):
build_dir = self.get_build_dir(arch)
assert build_dir.endswith(self.name)
shprint(sh.rm, '-rf', build_dir)
shprint(sh.mkdir, build_dir)
srcs = ('../../libs/able/able', 'setup.py')
for filename in srcs:
print(f"Copy {join(self.get_recipe_dir(), filename)} to {build_dir}")
shprint(sh.cp, '-a', join(self.get_recipe_dir(), filename),
build_dir)
def postbuild_arch(self, arch):
super(AbleRecipe, self).postbuild_arch(arch)
info('Copying able java class to classes build dir')
with current_directory(self.get_build_dir(arch.arch)):
shprint(sh.cp, '-a', join('able', 'src', 'org'),
self.ctx.javaclass_dir)
recipe = AbleRecipe()

View file

@ -0,0 +1,9 @@
from setuptools import setup
setup(
name='able',
version='0.0.0',
packages=['able', 'able.android'],
description='Bluetooth Low Energy for Android',
license='MIT',
)

View file

@ -2,6 +2,7 @@ from os.path import join
from pythonforandroid.recipe import Recipe
from pythonforandroid.toolchain import current_directory, shprint
import sh
import os
# For debugging, clean with
# buildozer android p4a -- clean_recipe_build codec2 --local-recipes ~/Information/Source/Sideband/recipes

View file

@ -0,0 +1,14 @@
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
class CythonRecipe(CompiledComponentsPythonRecipe):
version = '3.1.6'
url = 'https://github.com/cython/cython/archive/{version}.tar.gz'
site_packages_name = 'cython'
depends = ['setuptools']
call_hostpython_via_targetpython = False
install_in_hostpython = True
recipe = CythonRecipe()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,175 @@
import sh
import os
from multiprocessing import cpu_count
from pathlib import Path
from os.path import join
from packaging.version import Version
from pythonforandroid.logger import shprint
from pythonforandroid.recipe import Recipe
from pythonforandroid.util import (
BuildInterruptingException,
current_directory,
ensure_dir,
)
from pythonforandroid.prerequisites import OpenSSLPrerequisite
HOSTPYTHON_VERSION_UNSET_MESSAGE = (
'The hostpython recipe must have set version'
)
SETUP_DIST_NOT_FIND_MESSAGE = (
'Could not find Setup.dist or Setup in Python build'
)
class HostPython3Recipe(Recipe):
'''
The hostpython3's recipe.
.. versionchanged:: 2019.10.06.post0
Refactored from deleted class ``python.HostPythonRecipe`` into here.
.. versionchanged:: 0.6.0
Refactored into the new class
:class:`~pythonforandroid.python.HostPythonRecipe`
'''
version = '3.11.5'
name = 'hostpython3'
build_subdir = 'native-build'
'''Specify the sub build directory for the hostpython3 recipe. Defaults
to ``native-build``.'''
url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'
'''The default url to download our host python recipe. This url will
change depending on the python version set in attribute :attr:`version`.'''
patches = ['patches/pyconfig_detection.patch']
@property
def _exe_name(self):
'''
Returns the name of the python executable depending on the version.
'''
if not self.version:
raise BuildInterruptingException(HOSTPYTHON_VERSION_UNSET_MESSAGE)
return f'python{self.version.split(".")[0]}'
@property
def python_exe(self):
'''Returns the full path of the hostpython executable.'''
return join(self.get_path_to_python(), self._exe_name)
def get_recipe_env(self, arch=None):
env = os.environ.copy()
openssl_prereq = OpenSSLPrerequisite()
if env.get("PKG_CONFIG_PATH", ""):
env["PKG_CONFIG_PATH"] = os.pathsep.join(
[openssl_prereq.pkg_config_location, env["PKG_CONFIG_PATH"]]
)
else:
env["PKG_CONFIG_PATH"] = openssl_prereq.pkg_config_location
return env
def should_build(self, arch):
if Path(self.python_exe).exists():
# no need to build, but we must set hostpython for our Context
self.ctx.hostpython = self.python_exe
return False
return True
def get_build_container_dir(self, arch=None):
choices = self.check_recipe_choices()
dir_name = '-'.join([self.name] + choices)
return join(self.ctx.build_dir, 'other_builds', dir_name, 'desktop')
def get_build_dir(self, arch=None):
'''
.. note:: Unlike other recipes, the hostpython build dir doesn't
depend on the target arch
'''
return join(self.get_build_container_dir(), self.name)
def get_path_to_python(self):
return join(self.get_build_dir(), self.build_subdir)
@property
def site_root(self):
return join(self.get_path_to_python(), "root")
@property
def site_bin(self):
return join(self.site_root, self.site_dir, "bin")
@property
def local_bin(self):
return join(self.site_root, "usr/local/bin/")
@property
def site_dir(self):
p_version = Version(self.version)
return join(
self.site_root,
f"usr/local/lib/python{p_version.major}.{p_version.minor}/site-packages/"
)
def build_arch(self, arch):
env = self.get_recipe_env(arch)
recipe_build_dir = self.get_build_dir(arch.arch)
# Create a subdirectory to actually perform the build
build_dir = join(recipe_build_dir, self.build_subdir)
ensure_dir(build_dir)
# Configure the build
build_configured = False
with current_directory(build_dir):
if not Path('config.status').exists():
shprint(sh.Command(join(recipe_build_dir, 'configure')), _env=env)
build_configured = True
with current_directory(recipe_build_dir):
# Create the Setup file. This copying from Setup.dist is
# the normal and expected procedure before Python 3.8, but
# after this the file with default options is already named "Setup"
setup_dist_location = join('Modules', 'Setup.dist')
if Path(setup_dist_location).exists():
shprint(sh.cp, setup_dist_location,
join(build_dir, 'Modules', 'Setup'))
else:
# Check the expected file does exist
setup_location = join('Modules', 'Setup')
if not Path(setup_location).exists():
raise BuildInterruptingException(
SETUP_DIST_NOT_FIND_MESSAGE
)
shprint(sh.make, '-j', str(cpu_count()), '-C', build_dir, _env=env)
# make a copy of the python executable giving it the name we want,
# because we got different python's executable names depending on
# the fs being case-insensitive (Mac OS X, Cygwin...) or
# case-sensitive (linux)...so this way we will have an unique name
# for our hostpython, regarding the used fs
for exe_name in ['python.exe', 'python']:
exe = join(self.get_path_to_python(), exe_name)
if Path(exe).is_file():
shprint(sh.cp, exe, self.python_exe)
break
ensure_dir(self.site_root)
self.ctx.hostpython = self.python_exe
if build_configured:
print("RUNNING ENSUREPIP:"+self.site_root)
shprint(
sh.Command(self.python_exe), "-m", "ensurepip", "--root", self.site_root, "-U",
_env={"HOME": "/tmp"}
)
print("RAN ENSUREPIP")
recipe = HostPython3Recipe()

View file

@ -0,0 +1,13 @@
diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py
--- Python-3.8.2/Lib/site.py 2020-04-28 12:48:38.000000000 -0700
+++ Python-3.8.2-new/Lib/site.py 2020-04-28 12:52:46.000000000 -0700
@@ -487,7 +487,8 @@
if key == 'include-system-site-packages':
system_site = value.lower()
elif key == 'home':
- sys._home = value
+ # this is breaking pyconfig.h path detection with venv
+ print('Ignoring "sys._home = value" override', file=sys.stderr)
sys.prefix = sys.exec_prefix = site_prefix

View file

@ -0,0 +1,4 @@
APP_OPTIM := release
APP_ABI := all # or armeabi
APP_MODULES := libjpeg
APP_ALLOW_MISSING_DEPS := true

58
recipes/jpeg/__init__.py Normal file
View file

@ -0,0 +1,58 @@
from pythonforandroid.recipe import Recipe
from pythonforandroid.logger import shprint
from pythonforandroid.util import current_directory
from os.path import join
import sh
class JpegRecipe(Recipe):
'''
.. versionchanged:: 0.6.0
rewrote recipe to be build with clang and updated libraries to latest
version of the official git repo.
'''
name = 'jpeg'
version = '2.0.1'
url = 'https://github.com/libjpeg-turbo/libjpeg-turbo/archive/{version}.tar.gz' # noqa
built_libraries = {'libjpeg.a': '.', 'libturbojpeg.a': '.'}
# we will require this below patch to build the shared library
# patches = ['remove-version.patch']
def build_arch(self, arch):
build_dir = self.get_build_dir(arch.arch)
# TODO: Fix simd/neon
with current_directory(build_dir):
env = self.get_recipe_env(arch)
toolchain_file = join(self.ctx.ndk_dir,
'build/cmake/android.toolchain.cmake')
shprint(sh.rm, '-rf', 'CMakeCache.txt', 'CMakeFiles/')
shprint(sh.cmake, '-G', 'Unix Makefiles',
'-DCMAKE_SYSTEM_NAME=Android',
'-DCMAKE_POSITION_INDEPENDENT_CODE=1',
'-DCMAKE_ANDROID_ARCH_ABI={arch}'.format(arch=arch.arch),
'-DCMAKE_ANDROID_NDK=' + self.ctx.ndk_dir,
'-DCMAKE_C_COMPILER={cc}'.format(cc=arch.get_clang_exe()),
'-DCMAKE_CXX_COMPILER={cc_plus}'.format(
cc_plus=arch.get_clang_exe(plus_plus=True)),
'-DCMAKE_BUILD_TYPE=Release',
'-DCMAKE_INSTALL_PREFIX=./install',
'-DCMAKE_TOOLCHAIN_FILE=' + toolchain_file,
'-DANDROID_ABI={arch}'.format(arch=arch.arch),
'-DANDROID_ARM_NEON=ON',
'-DENABLE_NEON=ON',
# '-DREQUIRE_SIMD=1',
# Force disable shared, with the static ones is enough
'-DENABLE_SHARED=0',
'-DENABLE_STATIC=1',
# Fix cmake compatibility issue
'-DCMAKE_POLICY_VERSION_MINIMUM=3.5',
_env=env)
shprint(sh.make, _env=env)
recipe = JpegRecipe()

View file

@ -0,0 +1,85 @@
diff -Naur jpeg/Android.mk b/Android.mk
--- jpeg/Android.mk 2015-12-14 11:37:25.900190235 -0600
+++ b/Android.mk 2015-12-14 11:41:27.532182210 -0600
@@ -54,8 +54,7 @@
LOCAL_SRC_FILES:= $(libjpeg_SOURCES_DIST)
-LOCAL_SHARED_LIBRARIES := libcutils
-LOCAL_STATIC_LIBRARIES := libsimd
+LOCAL_STATIC_LIBRARIES := libsimd libcutils
LOCAL_C_INCLUDES := $(LOCAL_PATH)
@@ -68,7 +67,7 @@
LOCAL_MODULE := libjpeg
-include $(BUILD_SHARED_LIBRARY)
+include $(BUILD_STATIC_LIBRARY)
######################################################
### cjpeg ###
@@ -82,7 +81,7 @@
LOCAL_SRC_FILES:= $(cjpeg_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/android
@@ -110,7 +109,7 @@
LOCAL_SRC_FILES:= $(djpeg_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/android
@@ -137,7 +136,7 @@
LOCAL_SRC_FILES:= $(jpegtran_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/android
@@ -163,7 +162,7 @@
LOCAL_SRC_FILES:= $(tjunittest_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)
@@ -189,7 +188,7 @@
LOCAL_SRC_FILES:= $(tjbench_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)
@@ -215,7 +214,7 @@
LOCAL_SRC_FILES:= $(rdjpgcom_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)
@@ -240,7 +239,7 @@
LOCAL_SRC_FILES:= $(wrjpgcom_SOURCES)
-LOCAL_SHARED_LIBRARIES := libjpeg
+LOCAL_STATIC_LIBRARIES := libjpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)

View file

@ -0,0 +1,12 @@
--- jpeg/CMakeLists.txt.orig 2018-11-12 20:20:28.000000000 +0100
+++ jpeg/CMakeLists.txt 2018-12-14 12:43:45.338704504 +0100
@@ -573,6 +573,9 @@
add_library(turbojpeg SHARED ${TURBOJPEG_SOURCES})
set_property(TARGET turbojpeg PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
+ set_property(TARGET jpeg PROPERTY NO_SONAME 1)
+ set_property(TARGET turbojpeg PROPERTY NO_SONAME 1)
+ set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "")
if(WIN32)
set_target_properties(turbojpeg PROPERTIES DEFINE_SYMBOL DLLDEFINE)
endif()

View file

@ -1,75 +0,0 @@
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()

View file

@ -1,20 +0,0 @@
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

View file

@ -1,11 +0,0 @@
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)

View file

@ -1,28 +0,0 @@
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)

View file

@ -5,7 +5,7 @@ import sh
# class PyCodec2Recipe(IncludedFilesBehaviour, CythonRecipe):
class PyCodec2Recipe(CythonRecipe):
url = "https://github.com/markqvist/pycodec2/archive/refs/heads/main.zip"
url = "https://github.com/markqvist/pycodec2/archive/438ee4f2f3ee30635a34caddf520cfaccdbbc646.zip"
# src_filename = "../../../pycodec2"
depends = ["setuptools", "numpy", "Cython", "codec2"]
call_hostpython_via_targetpython = False

View file

@ -0,0 +1,44 @@
from pythonforandroid.recipe import PyProjectRecipe
from pythonforandroid.toolchain import shprint, current_directory, info
from pythonforandroid.patching import will_build
import sh
from os.path import join
class PyjniusRecipe(PyProjectRecipe):
version = '1.7.0'
url = 'https://github.com/kivy/pyjnius/archive/{version}.zip'
name = 'pyjnius'
depends = [('genericndkbuild', 'sdl2', 'sdl3'), 'six']
site_packages_name = 'jnius'
hostpython_prerequisites = ["Cython<3.2"]
patches = [
"use_cython.patch",
('genericndkbuild_jnienv_getter.patch', will_build('genericndkbuild')),
('sdl3_jnienv_getter.patch', will_build('sdl3')),
]
def get_recipe_env(self, arch, **kwargs):
env = super().get_recipe_env(arch, **kwargs)
# Taken from CythonRecipe
env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format(
self.ctx.get_libs_dir(arch.arch) +
' -L{} '.format(self.ctx.libs_dir) +
' -L{}'.format(join(self.ctx.bootstrap.build_dir, 'obj', 'local',
arch.arch)))
env['LDSHARED'] = env['CC'] + ' -shared'
env['LIBLINK'] = 'NOTNONE'
# NDKPLATFORM is our switch for detecting Android platform, so can't be None
env['NDKPLATFORM'] = "NOTNONE"
return env
def postbuild_arch(self, arch):
super().postbuild_arch(arch)
info('Copying pyjnius java class to classes build dir')
with current_directory(self.get_build_dir(arch.arch)):
shprint(sh.cp, '-a', join('jnius', 'src', 'org'), self.ctx.javaclass_dir)
recipe = PyjniusRecipe()

View file

@ -0,0 +1,24 @@
diff -Naur pyjnius.orig/jnius/env.py pyjnius/jnius/env.py
--- pyjnius.orig/jnius/env.py 2022-05-28 11:16:02.000000000 +0200
+++ pyjnius/jnius/env.py 2022-05-28 11:18:30.000000000 +0200
@@ -268,7 +268,7 @@
class AndroidJavaLocation(UnixJavaLocation):
def get_libraries(self):
- return ['SDL2', 'log']
+ return ['main', 'log']
def get_include_dirs(self):
# When cross-compiling for Android, we should not use the include dirs
diff -Naur pyjnius.orig/jnius/jnius_jvm_android.pxi pyjnius/jnius/jnius_jvm_android.pxi
--- pyjnius.orig/jnius/jnius_jvm_android.pxi 2022-05-28 11:16:02.000000000 +0200
+++ pyjnius/jnius/jnius_jvm_android.pxi 2022-05-28 11:17:17.000000000 +0200
@@ -1,6 +1,6 @@
# on android, rely on SDL to get the JNI env
-cdef extern JNIEnv *SDL_AndroidGetJNIEnv()
+cdef extern JNIEnv *WebView_AndroidGetJNIEnv()
cdef JNIEnv *get_platform_jnienv() except NULL:
- return <JNIEnv*>SDL_AndroidGetJNIEnv()
+ return <JNIEnv*>WebView_AndroidGetJNIEnv()

View file

@ -0,0 +1,24 @@
diff -Naur pyjnius.orig/jnius/env.py pyjnius/jnius/env.py
--- pyjnius.orig/jnius/env.py 2022-05-28 11:16:02.000000000 +0200
+++ pyjnius/jnius/env.py 2022-05-28 11:18:30.000000000 +0200
@@ -268,7 +268,7 @@
class AndroidJavaLocation(UnixJavaLocation):
def get_libraries(self):
- return ['SDL2', 'log']
+ return ['SDL3', 'log']
def get_include_dirs(self):
# When cross-compiling for Android, we should not use the include dirs
diff -Naur pyjnius.orig/jnius/jnius_jvm_android.pxi pyjnius/jnius/jnius_jvm_android.pxi
--- pyjnius.orig/jnius/jnius_jvm_android.pxi 2022-05-28 11:16:02.000000000 +0200
+++ pyjnius/jnius/jnius_jvm_android.pxi 2022-05-28 11:17:17.000000000 +0200
@@ -1,6 +1,6 @@
# on android, rely on SDL to get the JNI env
-cdef extern JNIEnv *SDL_AndroidGetJNIEnv()
+cdef extern JNIEnv *SDL_GetAndroidJNIEnv()
cdef JNIEnv *get_platform_jnienv() except NULL:
- return <JNIEnv*>SDL_AndroidGetJNIEnv()
+ return <JNIEnv*>SDL_GetAndroidJNIEnv()

View file

@ -0,0 +1,13 @@
--- pyjnius-1.6.1/setup.py 2023-11-05 21:07:43.000000000 +0530
+++ pyjnius-1.6.1.mod/setup.py 2025-03-01 14:47:11.964847337 +0530
@@ -59,10 +59,6 @@
if NDKPLATFORM is not None and getenv('LIBLINK'):
PLATFORM = 'android'
-# detect platform
-if PLATFORM == 'android':
- PYX_FILES = [fn[:-3] + 'c' for fn in PYX_FILES]
-
JAVA=get_java_setup(PLATFORM)
assert JAVA.is_jdk(), "You need a JDK, we only found a JRE. Try setting JAVA_HOME"

445
recipes/python3/__init__.py Normal file
View file

@ -0,0 +1,445 @@
import glob
import sh
import subprocess
from os import environ, utime
from os.path import dirname, exists, join
from pathlib import Path
import shutil
from pythonforandroid.logger import info, warning, shprint
from pythonforandroid.patching import version_starts_with
from pythonforandroid.recipe import Recipe, TargetPythonRecipe
from pythonforandroid.util import (
current_directory,
ensure_dir,
walk_valid_filens,
BuildInterruptingException,
)
NDK_API_LOWER_THAN_SUPPORTED_MESSAGE = (
'Target ndk-api is {ndk_api}, '
'but the python3 recipe supports only {min_ndk_api}+'
)
class Python3Recipe(TargetPythonRecipe):
'''
The python3's recipe
^^^^^^^^^^^^^^^^^^^^
The python 3 recipe can be built with some extra python modules, but to do
so, we need some libraries. By default, we ship the python3 recipe with
some common libraries, defined in ``depends``. We also support some optional
libraries, which are less common that the ones defined in ``depends``, so
we added them as optional dependencies (``opt_depends``).
Below you have a relationship between the python modules and the recipe
libraries::
- _ctypes: you must add the recipe for ``libffi``.
- _sqlite3: you must add the recipe for ``sqlite3``.
- _ssl: you must add the recipe for ``openssl``.
- _bz2: you must add the recipe for ``libbz2`` (optional).
- _lzma: you must add the recipe for ``liblzma`` (optional).
.. note:: This recipe can be built only against API 21+.
.. versionchanged:: 2019.10.06.post0
- Refactored from deleted class ``python.GuestPythonRecipe`` into here
- Added optional dependencies: :mod:`~pythonforandroid.recipes.libbz2`
and :mod:`~pythonforandroid.recipes.liblzma`
.. versionchanged:: 0.6.0
Refactored into class
:class:`~pythonforandroid.python.GuestPythonRecipe`
'''
version = '3.11.5'
url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'
name = 'python3'
patches = [
'patches/pyconfig_detection.patch',
'patches/reproducible-buildinfo.diff',
# Python 3.7.1
('patches/py3.7.1_fix-ctypes-util-find-library.patch', version_starts_with("3.7")),
('patches/py3.7.1_fix-zlib-version.patch', version_starts_with("3.7")),
# Python 3.8.1 & 3.9.X
('patches/py3.8.1.patch', version_starts_with("3.8")),
('patches/py3.8.1.patch', version_starts_with("3.9")),
('patches/py3.8.1.patch', version_starts_with("3.10")),
('patches/cpython-311-ctypes-find-library.patch', version_starts_with("3.11")),
]
if shutil.which('lld') is not None:
patches += [
("patches/py3.7.1_fix_cortex_a8.patch", version_starts_with("3.7")),
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.8")),
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.9")),
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.10")),
("patches/py3.8.1_fix_cortex_a8.patch", version_starts_with("3.11")),
]
depends = ['hostpython3', 'sqlite3', 'openssl', 'libffi']
# those optional depends allow us to build python compression modules:
# - _bz2.so
# - _lzma.so
opt_depends = ['libbz2', 'liblzma']
'''The optional libraries which we would like to get our python linked'''
configure_args = (
'--host={android_host}',
'--build={android_build}',
'--enable-shared',
'--enable-ipv6',
'ac_cv_file__dev_ptmx=yes',
'ac_cv_file__dev_ptc=no',
'--without-ensurepip',
'ac_cv_little_endian_double=yes',
'ac_cv_header_sys_eventfd_h=no',
'--prefix={prefix}',
'--exec-prefix={exec_prefix}',
'--enable-loadable-sqlite-extensions'
)
if version_starts_with("3.11"):
configure_args += ('--with-build-python={python_host_bin}',)
'''The configure arguments needed to build the python recipe. Those are
used in method :meth:`build_arch` (if not overwritten like python3's
recipe does).
'''
MIN_NDK_API = 21
'''Sets the minimal ndk api number needed to use the recipe.
.. warning:: This recipe can be built only against API 21+, so it means
that any class which inherits from class:`GuestPythonRecipe` will have
this limitation.
'''
stdlib_dir_blacklist = {
'__pycache__',
'test',
'tests',
'lib2to3',
'ensurepip',
'idlelib',
'tkinter',
}
'''The directories that we want to omit for our python bundle'''
stdlib_filen_blacklist = [
'*.py',
'*.exe',
'*.whl',
]
'''The file extensions that we want to blacklist for our python bundle'''
site_packages_dir_blacklist = {
'__pycache__',
'tests'
}
'''The directories from site packages dir that we don't want to be included
in our python bundle.'''
site_packages_filen_blacklist = [
'*.py'
]
'''The file extensions from site packages dir that we don't want to be
included in our python bundle.'''
compiled_extension = '.pyc'
'''the default extension for compiled python files.
.. note:: the default extension for compiled python files has been .pyo for
python 2.x-3.4 but as of Python 3.5, the .pyo filename extension is no
longer used and has been removed in favour of extension .pyc
'''
def __init__(self, *args, **kwargs):
self._ctx = None
super().__init__(*args, **kwargs)
@property
def _libpython(self):
'''return the python's library name (with extension)'''
return 'libpython{link_version}.so'.format(
link_version=self.link_version
)
@property
def link_version(self):
'''return the python's library link version e.g. 3.7m, 3.8'''
major, minor = self.major_minor_version_string.split('.')
flags = ''
if major == '3' and int(minor) < 8:
flags += 'm'
return '{major}.{minor}{flags}'.format(
major=major,
minor=minor,
flags=flags
)
def include_root(self, arch_name):
return join(self.get_build_dir(arch_name), 'Include')
def link_root(self, arch_name):
return join(self.get_build_dir(arch_name), 'android-build')
def should_build(self, arch):
return not Path(self.link_root(arch.arch), self._libpython).is_file()
def prebuild_arch(self, arch):
super().prebuild_arch(arch)
self.ctx.python_recipe = self
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
env = super().get_recipe_env(arch)
env['HOSTARCH'] = arch.command_prefix
env['CC'] = arch.get_clang_exe(with_target=True)
env['PATH'] = (
'{hostpython_dir}:{old_path}').format(
hostpython_dir=self.get_recipe(
'host' + self.name, self.ctx).get_path_to_python(),
old_path=env['PATH'])
env['CFLAGS'] = ' '.join(
[
'-fPIC',
'-DANDROID'
]
)
env['LDFLAGS'] = env.get('LDFLAGS', '')
if shutil.which('lld') is not None:
# Note: The -L. is to fix a bug in python 3.7.
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234409
env['LDFLAGS'] += ' -L. -fuse-ld=lld'
else:
warning('lld not found, linking without it. '
'Consider installing lld if linker errors occur.')
return env
def set_libs_flags(self, env, arch):
'''Takes care to properly link libraries with python depending on our
requirements and the attribute :attr:`opt_depends`.
'''
def add_flags(include_flags, link_dirs, link_libs):
env['CPPFLAGS'] = env.get('CPPFLAGS', '') + include_flags
env['LDFLAGS'] = env.get('LDFLAGS', '') + link_dirs
env['LIBS'] = env.get('LIBS', '') + link_libs
if 'sqlite3' in self.ctx.recipe_build_order:
info('Activating flags for sqlite3')
recipe = Recipe.get_recipe('sqlite3', self.ctx)
add_flags(' -I' + recipe.get_build_dir(arch.arch),
' -L' + recipe.get_lib_dir(arch), ' -lsqlite3')
if 'libffi' in self.ctx.recipe_build_order:
info('Activating flags for libffi')
recipe = Recipe.get_recipe('libffi', self.ctx)
# In order to force the correct linkage for our libffi library, we
# set the following variable to point where is our libffi.pc file,
# because the python build system uses pkg-config to configure it.
env['PKG_CONFIG_PATH'] = recipe.get_build_dir(arch.arch)
add_flags(' -I' + ' -I'.join(recipe.get_include_dirs(arch)),
' -L' + join(recipe.get_build_dir(arch.arch), '.libs'),
' -lffi')
if 'openssl' in self.ctx.recipe_build_order:
info('Activating flags for openssl')
recipe = Recipe.get_recipe('openssl', self.ctx)
self.configure_args += \
('--with-openssl=' + recipe.get_build_dir(arch.arch),)
add_flags(recipe.include_flags(arch),
recipe.link_dirs_flags(arch), recipe.link_libs_flags())
for library_name in {'libbz2', 'liblzma'}:
if library_name in self.ctx.recipe_build_order:
info(f'Activating flags for {library_name}')
recipe = Recipe.get_recipe(library_name, self.ctx)
add_flags(recipe.get_library_includes(arch),
recipe.get_library_ldflags(arch),
recipe.get_library_libs_flag())
# python build system contains hardcoded zlib version which prevents
# the build of zlib module, here we search for android's zlib version
# and sets the right flags, so python can be build with android's zlib
info("Activating flags for android's zlib")
zlib_lib_path = arch.ndk_lib_dir_versioned
zlib_includes = self.ctx.ndk.sysroot_include_dir
zlib_h = join(zlib_includes, 'zlib.h')
try:
with open(zlib_h) as fileh:
zlib_data = fileh.read()
except IOError:
raise BuildInterruptingException(
"Could not determine android's zlib version, no zlib.h ({}) in"
" the NDK dir includes".format(zlib_h)
)
for line in zlib_data.split('\n'):
if line.startswith('#define ZLIB_VERSION '):
break
else:
raise BuildInterruptingException(
'Could not parse zlib.h...so we cannot find zlib version,'
'required by python build,'
)
env['ZLIB_VERSION'] = line.replace('#define ZLIB_VERSION ', '')
add_flags(' -I' + zlib_includes, ' -L' + zlib_lib_path, ' -lz')
return env
def build_arch(self, arch):
if self.ctx.ndk_api < self.MIN_NDK_API:
raise BuildInterruptingException(
NDK_API_LOWER_THAN_SUPPORTED_MESSAGE.format(
ndk_api=self.ctx.ndk_api, min_ndk_api=self.MIN_NDK_API
),
)
recipe_build_dir = self.get_build_dir(arch.arch)
# Create a subdirectory to actually perform the build
build_dir = join(recipe_build_dir, 'android-build')
ensure_dir(build_dir)
# TODO: Get these dynamically, like bpo-30386 does
sys_prefix = '/usr/local'
sys_exec_prefix = '/usr/local'
env = self.get_recipe_env(arch)
env = self.set_libs_flags(env, arch)
android_build = sh.Command(
join(recipe_build_dir,
'config.guess'))().strip()
with current_directory(build_dir):
if not exists('config.status'):
shprint(
sh.Command(join(recipe_build_dir, 'configure')),
*(' '.join(self.configure_args).format(
android_host=env['HOSTARCH'],
android_build=android_build,
python_host_bin=join(self.get_recipe(
'host' + self.name, self.ctx
).get_path_to_python(), "python3"),
prefix=sys_prefix,
exec_prefix=sys_exec_prefix)).split(' '),
_env=env)
# Python build does not seem to play well with make -j option from Python 3.11 and onwards
# Before losing some time, please check issue
# https://github.com/python/cpython/issues/101295 , as the root cause looks similar
shprint(
sh.make,
'all',
'INSTSONAME={lib_name}'.format(lib_name=self._libpython),
_env=env
)
# TODO: Look into passing the path to pyconfig.h in a
# better way, although this is probably acceptable
sh.cp('pyconfig.h', join(recipe_build_dir, 'Include'))
def compile_python_files(self, dir):
'''
Compile the python files (recursively) for the python files inside
a given folder.
.. note:: python2 compiles the files into extension .pyo, but in
python3, and as of Python 3.5, the .pyo filename extension is no
longer used...uses .pyc (https://www.python.org/dev/peps/pep-0488)
'''
args = [self.ctx.hostpython]
args += ['-OO', '-m', 'compileall', '-b', '-f', dir]
subprocess.call(args)
def create_python_bundle(self, dirn, arch):
"""
Create a packaged python bundle in the target directory, by
copying all the modules and standard library to the right
place.
"""
# Todo: find a better way to find the build libs folder
modules_build_dir = join(
self.get_build_dir(arch.arch),
'android-build',
'build',
'lib.linux{}-{}-{}'.format(
'2' if self.version[0] == '2' else '',
arch.command_prefix.split('-')[0],
self.major_minor_version_string
))
# Compile to *.pyc the python modules
self.compile_python_files(modules_build_dir)
# Compile to *.pyc the standard python library
self.compile_python_files(join(self.get_build_dir(arch.arch), 'Lib'))
# Compile to *.pyc the other python packages (site-packages)
self.compile_python_files(self.ctx.get_python_install_dir(arch.arch))
# Bundle compiled python modules to a folder
modules_dir = join(dirn, 'modules')
c_ext = self.compiled_extension
ensure_dir(modules_dir)
module_filens = (glob.glob(join(modules_build_dir, '*.so')) +
glob.glob(join(modules_build_dir, '*' + c_ext)))
info("Copy {} files into the bundle".format(len(module_filens)))
for filen in module_filens:
info(" - copy {}".format(filen))
shutil.copy2(filen, modules_dir)
# zip up the standard library
stdlib_zip = join(dirn, 'stdlib.zip')
with current_directory(join(self.get_build_dir(arch.arch), 'Lib')):
stdlib_filens = list(walk_valid_filens(
'.', self.stdlib_dir_blacklist, self.stdlib_filen_blacklist))
if 'SOURCE_DATE_EPOCH' in environ:
# for reproducible builds
stdlib_filens.sort()
timestamp = int(environ['SOURCE_DATE_EPOCH'])
for filen in stdlib_filens:
utime(filen, (timestamp, timestamp))
info("Zip {} files into the bundle".format(len(stdlib_filens)))
shprint(sh.zip, '-X', stdlib_zip, *stdlib_filens)
# copy the site-packages into place
ensure_dir(join(dirn, 'site-packages'))
ensure_dir(self.ctx.get_python_install_dir(arch.arch))
# TODO: Improve the API around walking and copying the files
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))
info("Copy {} files into the site-packages".format(len(filens)))
for filen in filens:
info(" - copy {}".format(filen))
ensure_dir(join(dirn, 'site-packages', dirname(filen)))
shutil.copy2(filen, join(dirn, 'site-packages', filen))
# copy the python .so files into place
python_build_dir = join(self.get_build_dir(arch.arch),
'android-build')
python_lib_name = 'libpython' + self.link_version
shprint(
sh.cp,
join(python_build_dir, python_lib_name + '.so'),
join(self.ctx.bootstrap.dist_dir, 'libs', arch.arch)
)
info('Renaming .so files to reflect cross-compile')
self.reduce_object_file_names(join(dirn, 'site-packages'))
return join(dirn, 'site-packages')
recipe = Python3Recipe()

View file

@ -0,0 +1,19 @@
--- Python-3.11.5/Lib/ctypes/util.py 2023-08-24 17:39:18.000000000 +0530
+++ Python-3.11.5.mod/Lib/ctypes/util.py 2023-11-18 22:12:17.356160615 +0530
@@ -4,7 +4,15 @@
import sys
# find_library(name) returns the pathname of a library, or None.
-if os.name == "nt":
+
+# This patch overrides the find_library to look in the right places on
+# Android
+if True:
+ from android._ctypes_library_finder import find_library as _find_lib
+ def find_library(name):
+ return _find_lib(name)
+
+elif os.name == "nt":
def _get_build_version():
"""Return the version of MSVC that was used to build Python.

View file

@ -0,0 +1,15 @@
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -67,4 +67,11 @@
return fname
return None
+# This patch overrides the find_library to look in the right places on
+# Android
+if True:
+ from android._ctypes_library_finder import find_library as _find_lib
+ def find_library(name):
+ return _find_lib(name)
+
elif os.name == "posix" and sys.platform == "darwin":

View file

@ -0,0 +1,12 @@
--- Python-3.7.1/setup.py.orig 2018-10-20 08:04:19.000000000 +0200
+++ Python-3.7.1/setup.py 2019-02-17 00:24:30.715904412 +0100
@@ -1410,7 +1410,8 @@ class PyBuildExt(build_ext):
if zlib_inc is not None:
zlib_h = zlib_inc[0] + '/zlib.h'
version = '"0.0.0"'
- version_req = '"1.1.3"'
+ version_req = '"{}"'.format(
+ os.environ.get('ZLIB_VERSION', '1.1.3'))
if host_platform == 'darwin' and is_macosx_sdk_path(zlib_h):
zlib_h = os.path.join(macosx_sdk_root(), zlib_h[1:])
with open(zlib_h) as fp:

View file

@ -0,0 +1,14 @@
This patch removes --fix-cortex-a8 from the linker flags in order to support linking
with lld, as lld does not support this flag (https://github.com/android-ndk/ndk/issues/766).
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -5671,7 +5671,7 @@ $as_echo_n "checking for the Android arm ABI... " >&6; }
$as_echo "$_arm_arch" >&6; }
if test "$_arm_arch" = 7; then
BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16"
- LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8"
+ LDFLAGS="${LDFLAGS} -march=armv7-a"
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not Android" >&5

View file

@ -0,0 +1,42 @@
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
index 97973bc..053c231 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -67,6 +67,13 @@ if os.name == "nt":
return fname
return None
+# This patch overrides the find_library to look in the right places on
+# Android
+if True:
+ from android._ctypes_library_finder import find_library as _find_lib
+ def find_library(name):
+ return _find_lib(name)
+
elif os.name == "posix" and sys.platform == "darwin":
from ctypes.macholib.dyld import dyld_find as _dyld_find
def find_library(name):
diff --git a/configure b/configure
index 0914e24..dd00812 100755
--- a/configure
+++ b/configure
@@ -18673,4 +18673,3 @@ if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then
echo "" >&6
echo "" >&6
fi
-
diff --git a/setup.py b/setup.py
index 20d7f35..af15cc2 100644
--- a/setup.py
+++ b/setup.py
@@ -1501,7 +1501,9 @@ class PyBuildExt(build_ext):
if zlib_inc is not None:
zlib_h = zlib_inc[0] + '/zlib.h'
version = '"0.0.0"'
- version_req = '"1.1.3"'
+ # version_req = '"1.1.3"'
+ version_req = '"{}"'.format(
+ os.environ.get('ZLIB_VERSION', '1.1.3'))
if MACOS and is_macosx_sdk_path(zlib_h):
zlib_h = os.path.join(macosx_sdk_root(), zlib_h[1:])
with open(zlib_h) as fp:

View file

@ -0,0 +1,15 @@
This patch removes --fix-cortex-a8 from the linker flags in order to support linking
with lld, as lld does not support this flag (https://github.com/android-ndk/ndk/issues/766).
diff --git a/configure b/configure
index 0914e24..7517168 100755
--- a/configure
+++ b/configure
@@ -5642,7 +5642,7 @@ $as_echo_n "checking for the Android arm ABI... " >&6; }
$as_echo "$_arm_arch" >&6; }
if test "$_arm_arch" = 7; then
BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16"
- LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8"
+ LDFLAGS="${LDFLAGS} -march=armv7-a"
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not Android" >&5

View file

@ -0,0 +1,13 @@
diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py
--- Python-3.8.2/Lib/site.py 2020-04-28 12:48:38.000000000 -0700
+++ Python-3.8.2-new/Lib/site.py 2020-04-28 12:52:46.000000000 -0700
@@ -487,7 +487,8 @@
if key == 'include-system-site-packages':
system_site = value.lower()
elif key == 'home':
- sys._home = value
+ # this is breaking pyconfig.h path detection with venv
+ print('Ignoring "sys._home = value" override')
sys.prefix = sys.exec_prefix = site_prefix

View file

@ -0,0 +1,13 @@
# DP: Build getbuildinfo.o with DATE/TIME values when defined
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -785,6 +785,8 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \
-DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \
-DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \
-DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \
+ $(if $(BUILD_DATE),-DDATE='"$(BUILD_DATE)"') \
+ $(if $(BUILD_TIME),-DTIME='"$(BUILD_TIME)"') \
-o $@ $(srcdir)/Modules/getbuildinfo.c
Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile

View file

@ -0,0 +1,11 @@
LOCAL_PATH := $(call my-dir)/..
include $(CLEAR_VARS)
LOCAL_SRC_FILES := sqlite3.c
LOCAL_MODULE := sqlite3
LOCAL_CFLAGS := -DSQLITE_ENABLE_FTS4 -D_FILE_OFFSET_BITS=32 -DSQLITE_ENABLE_JSON1
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,36 @@
from os.path import join
import shutil
from pythonforandroid.recipe import NDKRecipe
from pythonforandroid.util import ensure_dir
class Sqlite3Recipe(NDKRecipe):
version = '3.35.5'
# Don't forget to change the URL when changing the version
url = 'https://www.sqlite.org/2021/sqlite-amalgamation-3350500.zip'
generated_libraries = ['sqlite3']
def should_build(self, arch):
return not self.has_libs(arch, 'libsqlite3.so')
def prebuild_arch(self, arch):
super().prebuild_arch(arch)
# Copy the Android make file
ensure_dir(join(self.get_build_dir(arch.arch), 'jni'))
shutil.copyfile(join(self.get_recipe_dir(), 'Android.mk'),
join(self.get_build_dir(arch.arch), 'jni/Android.mk'))
def build_arch(self, arch, *extra_args):
super().build_arch(arch)
# Copy the shared library
shutil.copyfile(join(self.get_build_dir(arch.arch), 'libs', arch.arch, 'libsqlite3.so'),
join(self.ctx.get_libs_dir(arch.arch), 'libsqlite3.so'))
def get_recipe_env(self, arch):
env = super().get_recipe_env(arch)
env['NDK_PROJECT_PATH'] = self.get_build_dir(arch.arch)
return env
recipe = Sqlite3Recipe()