Skip to content

Commit 4c10ba1

Browse files
committed
Update python2's recipe to version 2.7.15
All the build process of this recipe changes in favour of the recently refactored class TargetPythonRecipe References: d1c6875
1 parent 1fb789f commit 4c10ba1

39 files changed

+2532
-1516
lines changed
Lines changed: 51 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -1,225 +1,70 @@
1-
from pythonforandroid.recipe import TargetPythonRecipe, Recipe
2-
from pythonforandroid.toolchain import shprint, current_directory, info
3-
from pythonforandroid.patching import (is_darwin, is_api_gt,
4-
check_all, is_api_lt, is_ndk)
5-
from os.path import exists, join, realpath
6-
from os import walk
7-
import glob
8-
import sh
9-
10-
EXCLUDE_EXTS = (".py", ".pyc", ".so.o", ".so.a", ".so.libs", ".pyx")
1+
from pythonforandroid.recipe import TargetPythonRecipe
2+
from pythonforandroid.patching import (
3+
is_darwin, is_api_gt, check_all, is_api_lt, is_ndk)
114

125

136
class Python2Recipe(TargetPythonRecipe):
14-
version = "2.7.2"
15-
url = 'https://python.org/ftp/python/{version}/Python-{version}.tar.bz2'
7+
'''
8+
The python2's recipe.
9+
10+
.. versionchanged:: 0.6.0
11+
Updated to version 2.7.15 and the build process has been changed in
12+
favour of the recently changed class
13+
:class:`~pythonforandroid.recipe.TargetPythonRecipe`
14+
'''
15+
version = "2.7.15"
16+
url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'
1617
name = 'python2'
1718

1819
depends = ['hostpython2']
19-
conflicts = ['python3crystax', 'python3']
20-
opt_depends = ['openssl', 'sqlite3']
21-
22-
patches = ['patches/Python-{version}-xcompile.patch',
23-
'patches/Python-{version}-ctypes-disable-wchar.patch',
24-
'patches/disable-modules.patch',
25-
'patches/fix-locale.patch',
20+
conflicts = ['python3crystax', 'python3', 'python2legacy']
21+
# opt_depends = ['openssl', 'sqlite3']
22+
23+
patches = [
24+
# new 2.7.15 patches
25+
# ('patches/Python-2.7.15-fix-api-minor-than-21.patch',
26+
# is_api_lt(21)), # todo: this should be tested
27+
'patches/Python_{version}-ctypes-libffi-fix-configure.patch',
28+
'patches/ffi-config.sub-{version}.patch',
29+
'patches/fix-locale-{version}.patch',
30+
'patches/modules-locales-{version}.patch',
31+
'patches/fix-platform-{version}.patch',
32+
# migrated patches from 2.7.2
2633
'patches/fix-gethostbyaddr.patch',
27-
'patches/fix-setup-flags.patch',
2834
'patches/fix-filesystemdefaultencoding.patch',
2935
'patches/fix-termios.patch',
3036
'patches/custom-loader.patch',
31-
'patches/verbose-compilation.patch',
3237
'patches/fix-remove-corefoundation.patch',
3338
'patches/fix-dynamic-lookup.patch',
3439
'patches/fix-dlfcn.patch',
35-
'patches/parsetuple.patch',
36-
'patches/ctypes-find-library-updated.patch',
40+
'patches/ctypes-find-library.patch',
41+
'patches/Python-{version}-ctypes-disable-wchar.patch',
42+
'patches/disable-modules.patch',
43+
'patches/verbose-compilation.patch',
44+
# migrated special patches from 2.7.2
3745
('patches/fix-configure-darwin.patch', is_darwin),
3846
('patches/fix-distutils-darwin.patch', is_darwin),
3947
('patches/fix-ftime-removal.patch', is_api_gt(19)),
40-
('patches/disable-openpty.patch', check_all(is_api_lt(21), is_ndk('crystax')))]
41-
42-
from_crystax = False
43-
44-
def build_arch(self, arch):
45-
46-
if not exists(join(self.get_build_dir(arch.arch), 'libpython2.7.so')):
47-
self.do_python_build(arch)
48-
49-
if not exists(self.ctx.get_python_install_dir()):
50-
shprint(sh.cp, '-a', join(self.get_build_dir(arch.arch), 'python-install'),
51-
self.ctx.get_python_install_dir())
52-
53-
# This should be safe to run every time
54-
info('Copying hostpython binary to targetpython folder')
55-
shprint(sh.cp, self.ctx.hostpython,
56-
join(self.ctx.get_python_install_dir(), 'bin', 'python.host'))
57-
self.ctx.hostpython = join(self.ctx.get_python_install_dir(), 'bin', 'python.host')
58-
59-
if not exists(join(self.ctx.get_libs_dir(arch.arch), 'libpython2.7.so')):
60-
shprint(sh.cp, join(self.get_build_dir(arch.arch), 'libpython2.7.so'), self.ctx.get_libs_dir(arch.arch))
61-
62-
# # if exists(join(self.get_build_dir(arch.arch), 'libpython2.7.so')):
63-
# if exists(join(self.ctx.libs_dir, 'libpython2.7.so')):
64-
# info('libpython2.7.so already exists, skipping python build.')
65-
# if not exists(join(self.ctx.get_python_install_dir(), 'libpython2.7.so')):
66-
# info('Copying python-install to dist-dependent location')
67-
# shprint(sh.cp, '-a', 'python-install', self.ctx.get_python_install_dir())
68-
# self.ctx.hostpython = join(self.ctx.get_python_install_dir(), 'bin', 'python.host')
69-
70-
# return
71-
72-
def do_python_build(self, arch):
73-
74-
hostpython_recipe = Recipe.get_recipe('hostpython2', self.ctx)
75-
shprint(sh.cp, self.ctx.hostpython, self.get_build_dir(arch.arch))
76-
shprint(sh.cp, self.ctx.hostpgen, self.get_build_dir(arch.arch))
77-
hostpython = join(self.get_build_dir(arch.arch), 'hostpython')
78-
hostpgen = join(self.get_build_dir(arch.arch), 'hostpython')
79-
80-
with current_directory(self.get_build_dir(arch.arch)):
81-
82-
hostpython_recipe = Recipe.get_recipe('hostpython2', self.ctx)
83-
shprint(sh.cp, join(hostpython_recipe.get_recipe_dir(), 'Setup'), 'Modules')
84-
85-
env = arch.get_env()
86-
87-
env['HOSTARCH'] = 'arm-eabi'
88-
env['BUILDARCH'] = shprint(sh.gcc, '-dumpmachine').stdout.decode('utf-8').split('\n')[0]
89-
env['CFLAGS'] = ' '.join([env['CFLAGS'], '-DNO_MALLINFO'])
90-
91-
# TODO need to add a should_build that checks if optional
92-
# dependencies have changed (possibly in a generic way)
93-
if 'openssl' in self.ctx.recipe_build_order:
94-
recipe = Recipe.get_recipe('openssl', self.ctx)
95-
openssl_build_dir = recipe.get_build_dir(arch.arch)
96-
setuplocal = join('Modules', 'Setup.local')
97-
shprint(sh.cp, join(self.get_recipe_dir(), 'Setup.local-ssl'), setuplocal)
98-
shprint(sh.sed, '-i.backup', 's#^SSL=.*#SSL={}#'.format(openssl_build_dir), setuplocal)
99-
env['OPENSSL_VERSION'] = recipe.version
100-
101-
if 'sqlite3' in self.ctx.recipe_build_order:
102-
# Include sqlite3 in python2 build
103-
recipe = Recipe.get_recipe('sqlite3', self.ctx)
104-
include = ' -I' + recipe.get_build_dir(arch.arch)
105-
lib = ' -L' + recipe.get_lib_dir(arch) + ' -lsqlite3'
106-
# Insert or append to env
107-
flag = 'CPPFLAGS'
108-
env[flag] = env[flag] + include if flag in env else include
109-
flag = 'LDFLAGS'
110-
env[flag] = env[flag] + lib if flag in env else lib
111-
112-
# NDK has langinfo.h but doesn't define nl_langinfo()
113-
env['ac_cv_header_langinfo_h'] = 'no'
114-
configure = sh.Command('./configure')
115-
shprint(configure,
116-
'--host={}'.format(env['HOSTARCH']),
117-
'--build={}'.format(env['BUILDARCH']),
118-
# 'OPT={}'.format(env['OFLAG']),
119-
'--prefix={}'.format(realpath('./python-install')),
120-
'--enable-shared',
121-
'--disable-toolbox-glue',
122-
'--disable-framework',
123-
_env=env)
124-
125-
# tito left this comment in the original source. It's still true!
126-
# FIXME, the first time, we got a error at:
127-
# python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h
128-
# /home/tito/code/python-for-android/build/python/Python-2.7.2/python: 1: Syntax error: word unexpected (expecting ")")
129-
# because at this time, python is arm, not x86. even that, why /usr/include/netinet/in.h is used ?
130-
# check if we can avoid this part.
131-
132-
make = sh.Command(env['MAKE'].split(' ')[0])
133-
print('First install (expected to fail...')
134-
try:
135-
shprint(make, '-j5', 'install', 'HOSTPYTHON={}'.format(hostpython),
136-
'HOSTPGEN={}'.format(hostpgen),
137-
'CROSS_COMPILE_TARGET=yes',
138-
'INSTSONAME=libpython2.7.so',
139-
_env=env)
140-
except sh.ErrorReturnCode_2:
141-
print('First python2 make failed. This is expected, trying again.')
142-
143-
print('Second install (expected to work)')
144-
shprint(sh.touch, 'python.exe', 'python')
145-
shprint(make, '-j5', 'install', 'HOSTPYTHON={}'.format(hostpython),
146-
'HOSTPGEN={}'.format(hostpgen),
147-
'CROSS_COMPILE_TARGET=yes',
148-
'INSTSONAME=libpython2.7.so',
149-
_env=env)
150-
151-
if is_darwin():
152-
shprint(sh.cp, join(self.get_recipe_dir(), 'patches', '_scproxy.py'),
153-
join('python-install', 'Lib'))
154-
shprint(sh.cp, join(self.get_recipe_dir(), 'patches', '_scproxy.py'),
155-
join('python-install', 'lib', 'python2.7'))
156-
157-
# reduce python
158-
for dir_name in ('test', join('json', 'tests'), 'lib-tk',
159-
join('sqlite3', 'test'), join('unittest, test'),
160-
join('lib2to3', 'tests'), join('bsddb', 'tests'),
161-
join('distutils', 'tests'), join('email', 'test'),
162-
'curses'):
163-
shprint(sh.rm, '-rf', join('python-install',
164-
'lib', 'python2.7', dir_name))
165-
166-
# info('Copying python-install to dist-dependent location')
167-
# shprint(sh.cp, '-a', 'python-install', self.ctx.get_python_install_dir())
168-
169-
# print('Copying hostpython binary to targetpython folder')
170-
# shprint(sh.cp, self.ctx.hostpython,
171-
# join(self.ctx.get_python_install_dir(), 'bin', 'python.host'))
172-
# self.ctx.hostpython = join(self.ctx.get_python_install_dir(), 'bin', 'python.host')
173-
174-
# print('python2 build done, exiting for debug')
175-
# exit(1)
176-
177-
def create_python_bundle(self, dirn, arch):
178-
info("Filling private directory")
179-
if not exists(join(dirn, "lib")):
180-
info("lib dir does not exist, making")
181-
shprint(sh.cp, "-a",
182-
join("python-install", "lib"), dirn)
183-
shprint(sh.mkdir, "-p",
184-
join(dirn, "include", "python2.7"))
185-
186-
libpymodules_fn = join("libs", arch.arch, "libpymodules.so")
187-
if exists(libpymodules_fn):
188-
shprint(sh.mv, libpymodules_fn, dirn)
189-
shprint(sh.cp,
190-
join('python-install', 'include',
191-
'python2.7', 'pyconfig.h'),
192-
join(dirn, 'include', 'python2.7/'))
193-
194-
info('Removing some unwanted files')
195-
shprint(sh.rm, '-f', join(dirn, 'lib', 'libpython2.7.so'))
196-
shprint(sh.rm, '-rf', join(dirn, 'lib', 'pkgconfig'))
197-
198-
libdir = join(dirn, 'lib', 'python2.7')
199-
site_packages_dir = join(libdir, 'site-packages')
200-
with current_directory(libdir):
201-
removes = []
202-
for dirname, root, filenames in walk("."):
203-
for filename in filenames:
204-
for suffix in EXCLUDE_EXTS:
205-
if filename.endswith(suffix):
206-
removes.append(filename)
207-
shprint(sh.rm, '-f', *removes)
208-
209-
info('Deleting some other stuff not used on android')
210-
# To quote the original distribute.sh, 'well...'
211-
shprint(sh.rm, '-rf', 'lib2to3')
212-
shprint(sh.rm, '-rf', 'idlelib')
213-
shprint(sh.rm, '-f', *glob.glob('config/libpython*.a'))
214-
shprint(sh.rm, '-rf', 'config/python.o')
215-
216-
return site_packages_dir
217-
218-
def include_root(self, arch_name):
219-
return join(self.get_build_dir(arch_name), 'python-install', 'include', 'python2.7')
220-
221-
def link_root(self, arch_name):
222-
return join(self.get_build_dir(arch_name), 'python-install', 'lib')
48+
('patches/disable-openpty.patch', check_all(
49+
is_api_lt(21), is_ndk('crystax')))
50+
]
51+
52+
configure_args = ('--host={android_host}',
53+
'--build={android_build}',
54+
'--enable-shared',
55+
'--disable-ipv6',
56+
'--disable-toolbox-glue',
57+
'--disable-framework',
58+
'ac_cv_file__dev_ptmx=yes',
59+
'ac_cv_file__dev_ptc=no',
60+
'--without-ensurepip',
61+
'ac_cv_little_endian_double=yes',
62+
63+
# why python3 works without it?
64+
'ac_cv_header_langinfo_h=no',
65+
66+
'--prefix={prefix}',
67+
'--exec-prefix={exec_prefix}')
22368

22469

22570
recipe = Python2Recipe()
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
--- Python-2.7.15/Lib/ctypes/__init__.py.orig 2017-12-29 16:59:33.000000000 +0100
2+
+++ Python-2.7.15/Lib/ctypes/__init__.py 2017-12-29 17:00:15.636079979 +0100
3+
@@ -265,7 +265,7 @@
4+
if _os.name in ("nt", "ce"):
5+
_win_functype_cache.clear()
6+
# _SimpleCData.c_wchar_p_from_param
7+
- POINTER(c_wchar).from_param = c_wchar_p.from_param
8+
+ # POINTER(c_wchar).from_param = c_wchar_p.from_param
9+
# _SimpleCData.c_char_p_from_param
10+
POINTER(c_char).from_param = c_char_p.from_param
11+
_pointer_type_cache[None] = c_void_p
12+
@@ -285,29 +285,34 @@
13+
else:
14+
set_conversion_mode("ascii", "strict")
15+
16+
- class c_wchar_p(_SimpleCData):
17+
- _type_ = "Z"
18+
-
19+
- class c_wchar(_SimpleCData):
20+
- _type_ = "u"
21+
-
22+
- def create_unicode_buffer(init, size=None):
23+
- """create_unicode_buffer(aString) -> character array
24+
- create_unicode_buffer(anInteger) -> character array
25+
- create_unicode_buffer(aString, anInteger) -> character array
26+
- """
27+
- if isinstance(init, (str, unicode)):
28+
- if size is None:
29+
- size = len(init)+1
30+
- buftype = c_wchar * size
31+
- buf = buftype()
32+
- buf.value = init
33+
- return buf
34+
- elif isinstance(init, (int, long)):
35+
- buftype = c_wchar * init
36+
- buf = buftype()
37+
- return buf
38+
- raise TypeError(init)
39+
+# The wchar stuff causes a crash on Android (the bionic C library doesn't
40+
+# implement wchar_t anyway)
41+
+#
42+
+# class c_wchar_p(_SimpleCData):
43+
+# _type_ = "Z"
44+
+#
45+
+# class c_wchar(_SimpleCData):
46+
+# _type_ = "u"
47+
+#
48+
+# POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param
49+
+#
50+
+# def create_unicode_buffer(init, size=None):
51+
+# """create_unicode_buffer(aString) -> character array
52+
+# create_unicode_buffer(anInteger) -> character array
53+
+# create_unicode_buffer(aString, anInteger) -> character array
54+
+# """
55+
+# if isinstance(init, (str, unicode)):
56+
+# if size is None:
57+
+# size = len(init)+1
58+
+# buftype = c_wchar * size
59+
+# buf = buftype()
60+
+# buf.value = init
61+
+# return buf
62+
+# elif isinstance(init, (int, long)):
63+
+# buftype = c_wchar * init
64+
+# buf = buftype()
65+
+# return buf
66+
+# raise TypeError(init)
67+
68+
# XXX Deprecated
69+
def SetPointerType(pointer, cls):
70+
@@ -553,4 +558,4 @@
71+
elif sizeof(kind) == 8: c_uint64 = kind
72+
del(kind)
73+
74+
-_reset_cache()
75+
+_reset_cache()
76+
\ No hay ningún carácter de nueva línea al final del fichero

0 commit comments

Comments
 (0)