Skip to content

Commit c6cc367

Browse files
committed
Added python2 recipe build, plus associated fixes
1 parent e72d87d commit c6cc367

File tree

3 files changed

+125
-28
lines changed

3 files changed

+125
-28
lines changed

recipes/hostpython2/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ def build_armeabi(self):
2929

3030
if exists('hostpython'):
3131
print('hostpython already exists, skipping build')
32+
self.ctx.hostpython = join(self.get_build_dir('armeabi'),
33+
get_directory(self.versioned_url),
34+
'hostpython')
35+
self.ctx.hostpgen = join(self.get_build_dir('armeabi'),
36+
get_directory(self.versioned_url),
37+
'hostpgen')
3238
return
3339

3440
configure = sh.Command('./configure')

recipes/python2/__init__.py

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
from toolchain import Recipe, shprint
2+
from toolchain import Recipe, shprint, get_directory, current_directory, ArchAndroid
33
from os.path import exists, join
44
from os import uname
55
import sh
@@ -33,21 +33,83 @@ def prebuild_armeabi(self):
3333
self.apply_patch(join('patches', 'fix-configure-darwin.patch'))
3434
self.apply_patch(join('patches', 'fix-distutils-darwin.patch'))
3535

36-
shprint(sh.touch, join(build_dir, 'patched'))
37-
38-
39-
def build_arch(self, arch):
40-
# shprint(sh.xcodebuild,
41-
# "ONLY_ACTIVE_ARCH=NO",
42-
# "ARCHS={}".format(arch.arch),
43-
# "-sdk", arch.sdk,
44-
# "-project", "Xcode-iOS/SDL/SDL.xcodeproj",
45-
# "-tarelf.et", "libSDL",
46-
# "-configuration", "Release")
47-
env = self.get_recipe_env(arch)
48-
shprint(sh.ndk_build,
49-
"V=1", "sdl2",
50-
_env=env)
36+
shprint(sh.touch, join(build_dir, '.patched'))
37+
38+
def build_armeabi(self):
39+
if 'sqlite' in self.ctx.recipe_build_order or 'openssl' in self.ctx.recipe_build_order:
40+
print('sqlite or openssl support not yet enabled in python recipe')
41+
exit(1)
42+
43+
if exists(join(self.ctx.libs_dir, 'libpython2.7.so')):
44+
print('libpython2.7.so already exists, skipping python build.')
45+
return
46+
47+
with current_directory(self.get_actual_build_dir('armeabi')):
48+
49+
50+
hostpython_recipe = Recipe.get_recipe('hostpython2', self.ctx)
51+
shprint(sh.cp, join(hostpython_recipe.get_recipe_dir(), 'Setup'), 'Modules')
52+
53+
env = ArchAndroid(self.ctx).get_env()
54+
55+
configure = sh.Command('./configure')
56+
# AND: OFLAG isn't actually set, should it be?
57+
shprint(configure, '--host=arm-eabi',
58+
# 'OPT={}'.format(env['OFLAG']),
59+
'--prefix={}'.format(join(self.ctx.build_dir, 'python-install')),
60+
'--enable-shared',
61+
'--disable-toolbox-glue',
62+
'--disable-framefork',
63+
_env=env)
64+
65+
# AND: tito left this comment in the original source. It's still true!
66+
# FIXME, the first time, we got a error at:
67+
# python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h
68+
# /home/tito/code/python-for-android/build/python/Python-2.7.2/python: 1: Syntax error: word unexpected (expecting ")")
69+
# because at this time, python is arm, not x86. even that, why /usr/include/netinet/in.h is used ?
70+
# check if we can avoid this part.
71+
72+
make = sh.Command(env['MAKE'].split(' ')[0])
73+
print('First install (expected to fail...')
74+
try:
75+
shprint(make, '-j5', 'install', 'HOSTPYTHON={}'.format(self.ctx.hostpython),
76+
'HOSTPGEN={}'.format(self.ctx.hostpgen),
77+
'CROSS_COMPILE_TARGET=yes',
78+
'INSTSONAME=libpython2.7.so',
79+
_env=env)
80+
except sh.ErrorReturnCode_2:
81+
print('First python2 make failed. This is expected, trying again.')
82+
83+
84+
print('Second install (expected to work)')
85+
shprint(make, '-j5', 'install', 'HOSTPYTHON={}'.format(self.ctx.hostpython),
86+
'HOSTPGEN={}'.format(self.ctx.hostpgen),
87+
'CROSS_COMPILE_TARGET=yes',
88+
'INSTONAME=libpython2.7.so',
89+
_env=env)
90+
91+
if uname()[0] == 'Darwin':
92+
shprint(sh.cp, join(self.get_recipe_dir(), 'patches', '_scproxy.py'),
93+
join(self.get_actual_build_dir(), 'Lib'))
94+
shprint(sh.cp, join(self.get_recipe_dir(), 'patches', '_scproxy.py'),
95+
join(self.ctx.build_dir, 'python-install', 'lib', 'python2.7'))
96+
97+
print('Ready to copy .so for python arm')
98+
shprint(sh.cp, 'libpython2.7.so', self.ctx.libs_dir)
99+
100+
# reduce python?
101+
for dir_name in ('test', join('json', 'tests'), 'lib-tk',
102+
join('sqlite3', 'test'), join('unittest, test'),
103+
join('lib2to3', 'tests'), join('bsddb', 'tests'),
104+
join('distutils', 'tests'), join('email', 'test'),
105+
'curses'):
106+
shprint(sh.rm, '-rf', join(self.ctx.build_dir, 'python-install',
107+
'lib', 'python2.7', dir_name))
108+
109+
110+
111+
112+
51113

52114

53115
recipe = Python2Recipe()

toolchain.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import fnmatch
2222
import re
2323
from datetime import datetime
24+
from distutils.spawn import find_executable
2425
try:
2526
from urllib.request import FancyURLopener
2627
except ImportError:
@@ -182,17 +183,17 @@ def get_env(self):
182183
# env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
183184

184185
# AND: Added flags manually, removed $OFLAG
185-
env["OTHER_CFLAGS"] = " ".join(
186-
include_dirs)
187-
# AND:
186+
# env["OTHER_CFLAGS"] = " ".join(
187+
# include_dirs)
188+
189+
# env["OTHER_LDFLAGS"] = " ".join([
190+
# "-L{}/{}".format(self.ctx.dist_dir, "lib"),
191+
# ])
188192

189-
env["OTHER_LDFLAGS"] = " ".join([
190-
"-L{}/{}".format(self.ctx.dist_dir, "lib"),
191-
])
192193
env["CFLAGS"] = " ".join([
193194
"-DANDROID", "-mandroid", "-fomit-frame-pointer",
194-
"--sysroot", self.ctx.ndk_platform] +
195-
include_dirs)
195+
"--sysroot", self.ctx.ndk_platform])
196+
196197
env["CXXFLAGS"] = env["CFLAGS"]
197198

198199
env["LDFLAGS"] = " ".join(['-lm'])
@@ -212,12 +213,28 @@ def get_env(self):
212213
toolchain_version = '4.9'
213214
else:
214215
print('Error: NDK not supported by these tools?')
215-
exit()
216+
exit(1)
216217

217218
env['TOOLCHAIN_PREFIX'] = toolchain_prefix
218219
env['TOOLCHAIN_VERSION'] = toolchain_version
219220

220-
env['PATH'] = "{sdk_dir}/toolchains/{toolchain_prefix}-{toolchain_version}/prebuilt/{py_platform}-x86/bin/:{ndk_dir}/toolchains/{toolchain_prefix}-{toolchain_version}/prebuilt/{py_platform}-x86_64/bin/:{ndk_dir}:{sdk_dir}/tools:{path}".format(sdk_dir=self.ctx.sdk_dir, ndk_dir=self.ctx.ndk_dir, toolchain_prefix=toolchain_prefix, toolchain_version=toolchain_version, py_platform=py_platform, path=environ.get('PATH'))
221+
env['PATH'] = ('{ndk_dir}/toolchains/{toolchain_prefix}-{toolchain_version}/'
222+
'prebuilt/{py_platform}-x86/bin/:{ndk_dir}/toolchains/'
223+
'{toolchain_prefix}-{toolchain_version}/prebuilt/'
224+
'{py_platform}-x86_64/bin/:{ndk_dir}:{sdk_dir}/'
225+
'tools:{path}').format(
226+
sdk_dir=self.ctx.sdk_dir, ndk_dir=self.ctx.ndk_dir,
227+
toolchain_prefix=toolchain_prefix,
228+
toolchain_version=toolchain_version,
229+
py_platform=py_platform, path=environ.get('PATH'))
230+
231+
print('path is', env['PATH'])
232+
233+
cc = find_executable('{toolchain_prefix}-gcc'.format(
234+
toolchain_prefix=toolchain_prefix), path=env['PATH'])
235+
if cc is None:
236+
print('Couldn\'t find executable for CC. Exiting.')
237+
exit(1)
221238

222239
env['CC'] = '{toolchain_prefix}-gcc {cflags}'.format(
223240
toolchain_prefix=toolchain_prefix,
@@ -234,8 +251,6 @@ def get_env(self):
234251
env['MAKE'] = 'make -j5'
235252
env['READELF'] = '{}-readelf'.format(toolchain_prefix)
236253

237-
print('path is', env['PATH'])
238-
239254
return env
240255

241256

@@ -323,6 +338,7 @@ class Context(object):
323338
root_dir = None # the filepath of toolchain.py
324339
build_dir = None # in which bootstraps are copied for building and recipes are built
325340
dist_dir = None # the Android project folder where everything ends up
341+
libs_dir = None
326342
ccache = None # whether to use ccache
327343
cython = None # the cython interpreter name
328344

@@ -392,6 +408,7 @@ def __init__(self):
392408
self.root_dir = realpath(dirname(__file__))
393409
self.build_dir = "{}/build".format(self.root_dir)
394410
self.cache_dir = "{}/.cache".format(self.root_dir)
411+
self.libs_dir = join(self.build_dir, 'libs')
395412
self.dist_dir = "{}/dist".format(self.root_dir)
396413
# AND: Are the install_dir and include_dir the same for Android?
397414
self.install_dir = "{}/dist/root".format(self.root_dir)
@@ -436,6 +453,7 @@ def __init__(self):
436453
ensure_dir(self.cache_dir)
437454
ensure_dir(self.dist_dir)
438455
ensure_dir(self.install_dir)
456+
ensure_dir(self.libs_dir)
439457

440458
ensure_dir(join(self.build_dir, 'bootstrap_builds'))
441459
ensure_dir(join(self.build_dir, 'other_builds')) # where everything else is built
@@ -686,6 +704,10 @@ def name(self):
686704
def get_build_dir(self, arch):
687705
return join(self.ctx.build_dir, 'other_builds', self.name, arch)
688706

707+
def get_actual_build_dir(self, arch):
708+
return join(self.ctx.build_dir, 'other_builds', self.name, arch,
709+
get_directory(self.versioned_url))
710+
689711
def get_recipe_dir(self):
690712
# AND: Redundant, an equivalent property is already set by get_recipe
691713
return join(self.ctx.root_dir, 'recipes', self.name)
@@ -1401,6 +1423,13 @@ def create_android_project(self):
14011423

14021424
print('Done building recipes, exiting for now.')
14031425
return
1426+
1427+
def print_context_info(self):
1428+
ctx = Context()
1429+
for attribute in ('root_dir', 'build_dir', 'dist_dir', 'libs_dir',
1430+
'ccache', 'cython', 'sdk_dir', 'ndk_dir', 'ndk_platform',
1431+
'ndk_ver', 'android_api'):
1432+
print('{} is {}'.format(attribute, getattr(ctx, attribute)))
14041433

14051434

14061435
# def create(self):

0 commit comments

Comments
 (0)