Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
class IncludedFilesBehaviour(object):
'''Recipe mixin class that will automatically unpack files included in
the recipe directory.'''
src_filename = None
def prepare_build_dir(self, arch):
if self.src_filename is None:
print('IncludedFilesBehaviour failed: no src_filename specified')
exit(1)
shprint(sh.rm, '-rf', self.get_build_dir(arch))
shprint(sh.cp, '-a', join(self.get_recipe_dir(), self.src_filename),
self.get_build_dir(arch))
class BootstrapNDKRecipe(Recipe):
'''A recipe class for recipes built in an Android project jni dir with
an Android.mk. These are not cached separatly, but built in the
bootstrap's own building directory.
To build an NDK project which is not part of the bootstrap, see
:class:`~pythonforandroid.recipe.NDKRecipe`.
'''
dir_name = None # The name of the recipe build folder in the jni dir
def get_build_container_dir(self, arch):
return self.get_jni_dir()
def get_build_dir(self, arch):
if self.dir_name is None:
raise ValueError('{} recipe doesn\'t define a dir_name, but '
class IncludedFilesBehaviour(object):
'''Recipe mixin class that will automatically unpack files included in
the recipe directory.'''
src_filename = None
def prepare_build_dir(self, arch):
if self.src_filename is None:
print('IncludedFilesBehaviour failed: no src_filename specified')
exit(1)
shprint(sh.rm, '-rf', self.get_build_dir(arch))
shprint(sh.cp, '-a', join(self.get_recipe_dir(), self.src_filename),
self.get_build_dir(arch))
class BootstrapNDKRecipe(Recipe):
'''A recipe class for recipes built in an Android project jni dir with
an Android.mk. These are not cached separatly, but built in the
bootstrap's own building directory.
To build an NDK project which is not part of the bootstrap, see
:class:`~pythonforandroid.recipe.NDKRecipe`.
'''
dir_name = None # The name of the recipe build folder in the jni dir
def get_build_container_dir(self, arch):
return self.get_jni_dir()
def get_build_dir(self, arch):
if self.dir_name is None:
raise ValueError('{} recipe doesn\'t define a dir_name, but '
# Temporarily hardcode the -lpython3.x as this does not
# get applied automatically in some environments. This
# will need generalising, along with the other hardcoded
# py3.5 references, to support other python3 or crystax
# python versions.
if 'python2crystax' in self.ctx.recipe_build_order:
env['LDFLAGS'] += ' -lpython2.7'
else:
python3_version = self.ctx.python_recipe.version
python3_version = '.'.join(python3_version.split('.')[:2])
env['LDFLAGS'] += ' -lpython{}m'.format(python3_version)
return env
class TargetPythonRecipe(Recipe):
'''Class for target python recipes. Sets ctx.python_recipe to point to
itself, so as to know later what kind of Python was built or used.'''
from_crystax = False
'''True if the python is used from CrystaX, False otherwise (i.e. if
it is built by p4a).'''
def __init__(self, *args, **kwargs):
self._ctx = None
super(TargetPythonRecipe, self).__init__(*args, **kwargs)
def prebuild_arch(self, arch):
super(TargetPythonRecipe, self).prebuild_arch(arch)
if self.from_crystax and self.ctx.ndk != 'crystax':
error('The {} recipe can only be built when '
'using the CrystaX NDK. Exiting.'.format(self.name))
# Temporarily hardcode the -lpython3.x as this does not
# get applied automatically in some environments. This
# will need generalising, along with the other hardcoded
# py3.5 references, to support other python3 or crystax
# python versions.
if 'python2crystax' in self.ctx.recipe_build_order:
env['LDFLAGS'] += ' -lpython2.7'
else:
python3_version = self.ctx.python_recipe.version
python3_version = '.'.join(python3_version.split('.')[:2])
env['LDFLAGS'] += ' -lpython{}m'.format(python3_version)
return env
class TargetPythonRecipe(Recipe):
'''Class for target python recipes. Sets ctx.python_recipe to point to
itself, so as to know later what kind of Python was built or used.'''
from_crystax = False
'''True if the python is used from CrystaX, False otherwise (i.e. if
it is built by p4a).'''
def __init__(self, *args, **kwargs):
self._ctx = None
super(TargetPythonRecipe, self).__init__(*args, **kwargs)
def prebuild_arch(self, arch):
super(TargetPythonRecipe, self).prebuild_arch(arch)
if self.from_crystax and self.ctx.ndk != 'crystax':
error('The {} recipe can only be built when '
'using the CrystaX NDK. Exiting.'.format(self.name))
filens = shprint(sh.find, site_packages_dir, '-iname', '*.so').stdout.decode(
'utf-8').split('\n')[:-1]
for filen in filens:
parts = filen.split('.')
if len(parts) <= 2:
continue
shprint(sh.mv, filen, filen.split('.')[0] + '.so')
site_packages_dir = join(abspath(curdir),
site_packages_dir)
self.strip_libraries(arch)
self.fry_eggs(site_packages_dir)
super(PlainBootstrap, self).run_distribute()
bootstrap = PlainBootstrap()
info('Renaming .so files to reflect cross-compile')
site_packages_dir = 'python/site-packages'
filens = shprint(sh.find, site_packages_dir, '-iname', '*.so').stdout.decode(
'utf-8').split('\n')[:-1]
for filen in filens:
parts = filen.split('.')
if len(parts) <= 2:
continue
shprint(sh.mv, filen, filen.split('.')[0] + '.so')
site_packages_dir = join(abspath(curdir),
site_packages_dir)
self.strip_libraries(arch)
self.fry_eggs(site_packages_dir)
super(PlainBootstrap, self).run_distribute()
dir_name = None # The name of the recipe build folder in the jni dir
def get_build_container_dir(self, arch):
return self.get_jni_dir()
def get_build_dir(self, arch):
if self.dir_name is None:
raise ValueError('{} recipe doesn\'t define a dir_name, but '
'this is necessary'.format(self.name))
return join(self.get_build_container_dir(arch), self.dir_name)
def get_jni_dir(self):
return join(self.ctx.bootstrap.build_dir, 'jni')
class NDKRecipe(Recipe):
'''A recipe class for any NDK project not included in the bootstrap.'''
generated_libraries = []
def should_build(self, arch):
lib_dir = self.get_lib_dir(arch)
for lib in self.generated_libraries:
if not exists(join(lib_dir, lib)):
return True
return False
def get_lib_dir(self, arch):
return join(self.get_build_dir(arch.arch), 'obj', 'local', arch.arch)
def real_hostpython_location(self):
if 'hostpython2' in self.ctx.recipe_build_order:
return join(
Recipe.get_recipe('hostpython2', self.ctx).get_build_dir(),
'hostpython')
else:
python_recipe = self.ctx.python_recipe
return 'python{}'.format(python_recipe.version)
def get_lib_dir(self, arch):
return join(self.get_build_dir(arch.arch), 'obj', 'local', arch.arch)
def get_jni_dir(self, arch):
return join(self.get_build_dir(arch.arch), 'jni')
def build_arch(self, arch, *extra_args):
super(NDKRecipe, self).build_arch(arch)
env = self.get_recipe_env(arch)
with current_directory(self.get_build_dir(arch.arch)):
shprint(sh.ndk_build, 'V=1', 'APP_ABI=' + arch.arch, *extra_args, _env=env)
class PythonRecipe(Recipe):
site_packages_name = None
'''The name of the module's folder when installed in the Python
site-packages (e.g. for pyjnius it is 'jnius')'''
call_hostpython_via_targetpython = True
'''If True, tries to install the module using the hostpython binary
copied to the target (normally arm) python build dir. However, this
will fail if the module tries to import e.g. _io.so. Set this to False
to call hostpython from its own build dir, installing the module in
the right place via arguments to setup.py. However, this may not set
the environment correctly and so False is not the default.'''
install_in_hostpython = False
'''If True, additionally installs the module in the hostpython build
dir. This will make it available to other recipes if
call_hostpython_via_targetpython is False.
def build_arch(self, arch):
'''Build any cython components, then install the Python module by
calling setup.py install with the target Python dir.
'''
Recipe.build_arch(self, arch)
self.build_compiled_components(arch)
self.install_python_package(arch)