Skip to content

Commit 3d3fc1e

Browse files
committed
Add ability of compile our python installation files into (.pyc/.pyo) depending on our python version
Because this way the initialization of our apk it will be faster. We must use the .pyc extension for our python 3 because as of Python 3.5, the .pyo filename extension is no longer used and has been removed. Notice that the command to compile the files for python 3 is slightly different (`-b` option added). This is done that way because otherwise our compiled files would be put in `__pycache__` folder and this option makes that the compiled files gets putted in the same directory than the compiled file. See also: - `PEP 488 -- Elimination of PYO files` (https://www.python.org/dev/peps/pep-0488/) - `PEP 3147 -- PYC Repository Directories` as to why a separate directory is used (https://www.python.org/dev/peps/pep-3147/)
1 parent 142552a commit 3d3fc1e

File tree

2 files changed

+47
-12
lines changed

2 files changed

+47
-12
lines changed

pythonforandroid/python.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from os.path import dirname, exists, join
77
from shutil import copy2
88
from os import environ
9+
import subprocess
910
import glob
1011
import sh
1112

@@ -71,7 +72,7 @@ class GuestPythonRecipe(TargetPythonRecipe):
7172
'''The directories that we want to omit for our python bundle'''
7273

7374
stdlib_filen_blacklist = [
74-
'*.pyc',
75+
'*.py',
7576
'*.exe',
7677
'*.whl',
7778
]
@@ -84,13 +85,23 @@ class GuestPythonRecipe(TargetPythonRecipe):
8485
'''The directories from site packages dir that we don't want to be included
8586
in our python bundle.'''
8687

87-
site_packages_filen_blacklist = []
88+
site_packages_filen_blacklist = [
89+
'*.py'
90+
]
8891
'''The file extensions from site packages dir that we don't want to be
8992
included in our python bundle.'''
9093

9194
opt_depends = ['sqlite3', 'libffi', 'openssl']
9295
'''The optional libraries which we would like to get our python linked'''
9396

97+
compiled_extension = '.pyc'
98+
'''the default extension for compiled python files.
99+
100+
.. note:: the default extension for compiled python files has been .pyo for
101+
python 2.x-3.4 but as of Python 3.5, the .pyo filename extension is no
102+
longer used and has been removed in favour of extension .pyc
103+
'''
104+
94105
def __init__(self, *args, **kwargs):
95106
self._ctx = None
96107
super(GuestPythonRecipe, self).__init__(*args, **kwargs)
@@ -249,26 +260,48 @@ def include_root(self, arch_name):
249260
def link_root(self, arch_name):
250261
return join(self.get_build_dir(arch_name), 'android-build')
251262

263+
def compile_python_files(self, dir):
264+
'''
265+
Compile the python files (recursively) for the python files inside
266+
a given folder.
267+
268+
.. note:: python2 compiles the files into extension .pyo, but in
269+
python3, and as of Python 3.5, the .pyo filename extension is no
270+
longer used...uses .pyc (https://www.python.org/dev/peps/pep-0488)
271+
'''
272+
args = [self.ctx.hostpython]
273+
# Todo: make dynamic `-OO`, strip docstrings, via `--no-optimize-python`
274+
if self.ctx.python_recipe.name == 'python3':
275+
args += ['-OO', '-m', 'compileall', '-b', '-f', dir]
276+
else:
277+
args += ['-OO', '-m', 'compileall', '-f', dir]
278+
subprocess.call(args)
279+
252280
def create_python_bundle(self, dirn, arch):
253281
"""
254282
Create a packaged python bundle in the target directory, by
255283
copying all the modules and standard library to the right
256284
place.
257285
"""
286+
# Todo: find a better way to find the build libs folder
287+
modules_build_dir = join(
288+
self.get_build_dir(arch.arch), 'android-build', 'build',
289+
'lib.linux{}-arm-{}'.format('2' if self.version[0] == '2' else '',
290+
self.major_minor_version_string))
291+
292+
# Compile to *.pyc/*.pyo the python modules
293+
self.compile_python_files(modules_build_dir)
294+
# Compile to *.pyc/*.pyo the standard python library
295+
self.compile_python_files(join(self.get_build_dir(arch.arch), 'Lib'))
296+
# Compile to *.pyc/*.pyo the other python packages (site-packages)
297+
self.compile_python_files(self.ctx.get_python_install_dir())
298+
258299
# Bundle compiled python modules to a folder
259300
modules_dir = join(dirn, 'modules')
301+
c_ext = self.compiled_extension
260302
ensure_dir(modules_dir)
261-
# Todo: find a better way to find the build libs folder
262-
modules_build_dir = join(
263-
self.get_build_dir(arch.arch),
264-
'android-build',
265-
'build',
266-
'lib.linux{}-arm-{}'.format(
267-
'2' if self.version[0] == '2' else '',
268-
self.major_minor_version_string
269-
))
270303
module_filens = (glob.glob(join(modules_build_dir, '*.so')) +
271-
glob.glob(join(modules_build_dir, '*.py')))
304+
glob.glob(join(modules_build_dir, '*' + c_ext)))
272305
info("Copy {} files into the bundle".format(len(module_filens)))
273306
for filen in module_filens:
274307
info(" - copy {}".format(filen))

pythonforandroid/recipes/python2/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class Python2Recipe(GuestPythonRecipe):
4747
'--prefix={prefix}',
4848
'--exec-prefix={exec_prefix}')
4949

50+
compiled_extension = '.pyo'
51+
5052
def prebuild_arch(self, arch):
5153
super(Python2Recipe, self).prebuild_arch(arch)
5254
patch_mark = join(self.get_build_dir(arch.arch), '.openssl-patched')

0 commit comments

Comments
 (0)