Skip to content

Commit 1f2612b

Browse files
committed
Modfied SDL2 recipe and bootstrap for python3
1 parent c4e2b89 commit 1f2612b

6 files changed

Lines changed: 178 additions & 72 deletions

File tree

pythonforandroid/bootstrap.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ def _unpack_aar(self, aar, arch):
216216

217217
def strip_libraries(self, arch):
218218
info('Stripping libraries')
219+
if self.ctx.ndk_is_crystax:
220+
info('NDK is CrystaX, skipping')
221+
return
219222
env = arch.get_env()
220223
strip = which('arm-linux-androideabi-strip', env['PATH'])
221224
if strip is None:

pythonforandroid/bootstraps/sdl2/__init__.py

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,57 +30,69 @@ def run_distribute(self):
3030

3131
if not exists('private') and not self.ctx.ndk_is_crystax:
3232
shprint(sh.mkdir, 'private')
33-
if not exists('crystax_python') and self.ctx..ndk_is_crystax:
34-
shprint(sh.mkdir, 'crytax_python')
33+
if not exists('crystax_python') and self.ctx.ndk_is_crystax:
34+
shprint(sh.mkdir, 'crystax_python')
3535
if not exists('assets'):
3636
shprint(sh.mkdir, 'assets')
3737

3838
hostpython = sh.Command(self.ctx.hostpython)
39-
shprint(hostpython, '-OO', '-m', 'compileall',
40-
self.ctx.get_python_install_dir(),
41-
_tail=10, _filterout="^Listing", _critical=True)
42-
if not exists('python-install'):
43-
shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install')
39+
if not self.ctx.ndk_is_crystax:
40+
shprint(hostpython, '-OO', '-m', 'compileall',
41+
self.ctx.get_python_install_dir(),
42+
_tail=10, _filterout="^Listing", _critical=True)
43+
if not exists('python-install'):
44+
shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install')
4445

4546
self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)])
4647
self.distribute_aars(arch)
4748
self.distribute_javaclasses(self.ctx.javaclass_dir)
4849

49-
info('Filling private directory')
50-
if not exists(join('private', 'lib')):
51-
info('private/lib does not exist, making')
52-
shprint(sh.cp, '-a', join('python-install', 'lib'), 'private')
53-
shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7'))
50+
if not self.ctx.ndk_is_crystax:
51+
info('Filling private directory')
52+
if not exists(join('private', 'lib')):
53+
info('private/lib does not exist, making')
54+
shprint(sh.cp, '-a', join('python-install', 'lib'), 'private')
55+
shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7'))
5456

55-
# AND: Copylibs stuff should go here
56-
if exists(join('libs', arch.arch, 'libpymodules.so')):
57-
shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/')
58-
shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/'))
57+
# AND: Copylibs stuff should go here
58+
if exists(join('libs', arch.arch, 'libpymodules.so')):
59+
shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/')
60+
shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/'))
5961

60-
info('Removing some unwanted files')
61-
shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so'))
62-
shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig'))
62+
info('Removing some unwanted files')
63+
shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so'))
64+
shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig'))
6365

64-
with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')):
65-
# shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.')))
66-
removes = []
67-
for dirname, something, filens in walk('.'):
68-
for filename in filens:
69-
for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'):
70-
if filename.endswith(suffix):
71-
removes.append(filename)
72-
shprint(sh.rm, '-f', *removes)
66+
with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')):
67+
# shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.')))
68+
removes = []
69+
for dirname, something, filens in walk('.'):
70+
for filename in filens:
71+
for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'):
72+
if filename.endswith(suffix):
73+
removes.append(filename)
74+
shprint(sh.rm, '-f', *removes)
7375

74-
info('Deleting some other stuff not used on android')
75-
# To quote the original distribute.sh, 'well...'
76-
# shprint(sh.rm, '-rf', 'ctypes')
77-
shprint(sh.rm, '-rf', 'lib2to3')
78-
shprint(sh.rm, '-rf', 'idlelib')
79-
for filename in glob.glob('config/libpython*.a'):
80-
shprint(sh.rm, '-f', filename)
81-
shprint(sh.rm, '-rf', 'config/python.o')
82-
# shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so')
83-
# shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so')
76+
info('Deleting some other stuff not used on android')
77+
# To quote the original distribute.sh, 'well...'
78+
# shprint(sh.rm, '-rf', 'ctypes')
79+
shprint(sh.rm, '-rf', 'lib2to3')
80+
shprint(sh.rm, '-rf', 'idlelib')
81+
for filename in glob.glob('config/libpython*.a'):
82+
shprint(sh.rm, '-f', filename)
83+
shprint(sh.rm, '-rf', 'config/python.o')
84+
# shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so')
85+
# shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so')
86+
87+
else: # NDK *is* crystax
88+
ndk_dir = self.ctx.ndk_dir
89+
python_dir = join(ndk_dir, 'sources', 'python', '3.5',
90+
'libs', arch.arch)
91+
92+
shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/')
93+
shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/')
94+
shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/site-packages')
95+
8496

8597
self.strip_libraries(arch)
8698
super(SDL2Bootstrap, self).run_distribute()

pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
1212
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
1313
start.c
1414

15-
LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7
15+
# LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7
1616

17-
LOCAL_SHARED_LIBRARIES := SDL2
17+
LOCAL_SHARED_LIBRARIES := SDL2 python_shared
1818

19-
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lpython2.7
19+
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog #-lpython2.7
2020

21-
LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS)
21+
# LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS)
2222

2323
include $(BUILD_SHARED_LIBRARY)
24+
25+
$(call import-module,python/3.5)

pythonforandroid/bootstraps/sdl2/build/jni/src/start.c

Lines changed: 112 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,32 @@ static PyMethodDef AndroidEmbedMethods[] = {
3939
{NULL, NULL, 0, NULL}
4040
};
4141

42+
static struct PyModuleDef androidembed =
43+
{
44+
PyModuleDef_HEAD_INIT,
45+
"androidembed",
46+
"",
47+
-1,
48+
AndroidEmbedMethods
49+
};
50+
4251
PyMODINIT_FUNC initandroidembed(void) {
43-
(void) Py_InitModule("androidembed", AndroidEmbedMethods);
52+
return PyModule_Create(&androidembed);
53+
/* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */
54+
}
55+
56+
int dir_exists(char* filename)
57+
/* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# */
58+
{
59+
if (0 != access("filename", F_OK)) {
60+
if (ENOENT == errno) {
61+
return 0;
62+
}
63+
if (ENOTDIR == errno) {
64+
return 0;
65+
}
66+
return 1;
67+
}
4468
}
4569

4670
int file_exists(const char * filename)
@@ -78,38 +102,71 @@ int main(int argc, char *argv[]) {
78102
/* LOG(argv[0]); */
79103
/* LOG("AND: That was argv 0"); */
80104
//setenv("PYTHONVERBOSE", "2", 1);
81-
Py_SetProgramName(argv[0]);
105+
Py_SetProgramName(L"android_python");
106+
107+
/* our logging module for android
108+
*/
109+
PyImport_AppendInittab("androidembed", initandroidembed);
110+
111+
if (dir_exists("crystax_python/")) {
112+
char paths[256];
113+
snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument);
114+
/* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */
115+
LOG("calculated paths to be...");
116+
LOG(paths);
117+
118+
wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL);
119+
Py_SetPath(wchar_paths);
120+
LOG("set wchar paths...");
121+
}
122+
82123
Py_Initialize();
83-
PySys_SetArgv(argc, argv);
84124

85-
LOG("AND: Set program name");
125+
if (dir_exists("private/")) {
126+
PySys_SetArgv(argc, argv);
127+
}
128+
129+
LOG("Initialized python");
86130

87131
/* ensure threads will work.
88132
*/
89-
PyEval_InitThreads();
90-
91133
LOG("AND: Init threads");
134+
PyEval_InitThreads();
135+
92136

93-
/* our logging module for android
94-
*/
95-
initandroidembed();
96-
97-
LOG("AND: Init embed");
137+
PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')");
138+
LOG("tried to run simple androidembed test");
98139

99140
/* inject our bootstrap code to redirect python stdin/stdout
100141
* replace sys.path with our path
101142
*/
143+
PyRun_SimpleString("import sys, posix\n");
144+
if (dir_exists("private/")) {
145+
/* If we built our own python, set up the paths correctly */
146+
PyRun_SimpleString(
147+
"private = posix.environ['ANDROID_PRIVATE']\n" \
148+
"argument = posix.environ['ANDROID_ARGUMENT']\n" \
149+
"sys.path[:] = [ \n" \
150+
" private + '/lib/python27.zip', \n" \
151+
" private + '/lib/python2.7/', \n" \
152+
" private + '/lib/python2.7/lib-dynload/', \n" \
153+
" private + '/lib/python2.7/site-packages/', \n" \
154+
" argument ]\n");
155+
} else {
156+
157+
char add_site_packages_dir[256];
158+
snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')",
159+
env_argument);
160+
161+
PyRun_SimpleString(
162+
"import sys\n" \
163+
"sys.argv = ['notaninterpreterreally']\n" \
164+
"from os.path import realpath, join, dirname");
165+
PyRun_SimpleString(add_site_packages_dir);
166+
/* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
167+
}
168+
102169
PyRun_SimpleString(
103-
"import sys, posix\n" \
104-
"private = posix.environ['ANDROID_PRIVATE']\n" \
105-
"argument = posix.environ['ANDROID_ARGUMENT']\n" \
106-
"sys.path[:] = [ \n" \
107-
" private + '/lib/python27.zip', \n" \
108-
" private + '/lib/python2.7/', \n" \
109-
" private + '/lib/python2.7/lib-dynload/', \n" \
110-
" private + '/lib/python2.7/site-packages/', \n" \
111-
" argument ]\n" \
112-
"import androidembed\n" \
113170
"class LogFile(object):\n" \
114171
" def __init__(self):\n" \
115172
" self.buffer = ''\n" \
@@ -122,9 +179,37 @@ int main(int argc, char *argv[]) {
122179
" def flush(self):\n" \
123180
" return\n" \
124181
"sys.stdout = sys.stderr = LogFile()\n" \
125-
"import site; print site.getsitepackages()\n"\
126-
"print 'Android path', sys.path\n" \
127-
"print 'Android kivy bootstrap done. __name__ is', __name__");
182+
"print('Android path', sys.path)\n" \
183+
"import os\n" \
184+
"print('os.environ is', os.environ)\n" \
185+
"print('Android kivy bootstrap done. __name__ is', __name__)");
186+
187+
/* PyRun_SimpleString( */
188+
/* "import sys, posix\n" \ */
189+
/* "private = posix.environ['ANDROID_PRIVATE']\n" \ */
190+
/* "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */
191+
/* "sys.path[:] = [ \n" \ */
192+
/* " private + '/lib/python27.zip', \n" \ */
193+
/* " private + '/lib/python2.7/', \n" \ */
194+
/* " private + '/lib/python2.7/lib-dynload/', \n" \ */
195+
/* " private + '/lib/python2.7/site-packages/', \n" \ */
196+
/* " argument ]\n" \ */
197+
/* "import androidembed\n" \ */
198+
/* "class LogFile(object):\n" \ */
199+
/* " def __init__(self):\n" \ */
200+
/* " self.buffer = ''\n" \ */
201+
/* " def write(self, s):\n" \ */
202+
/* " s = self.buffer + s\n" \ */
203+
/* " lines = s.split(\"\\n\")\n" \ */
204+
/* " for l in lines[:-1]:\n" \ */
205+
/* " androidembed.log(l)\n" \ */
206+
/* " self.buffer = lines[-1]\n" \ */
207+
/* " def flush(self):\n" \ */
208+
/* " return\n" \ */
209+
/* "sys.stdout = sys.stderr = LogFile()\n" \ */
210+
/* "import site; print site.getsitepackages()\n"\ */
211+
/* "print 'Android path', sys.path\n" \ */
212+
/* "print 'Android kivy bootstrap done. __name__ is', __name__"); */
128213

129214
LOG("AND: Ran string");
130215
/* run it !
@@ -160,8 +245,9 @@ int main(int argc, char *argv[]) {
160245
if (PyErr_Occurred() != NULL) {
161246
ret = 1;
162247
PyErr_Print(); /* This exits with the right code if SystemExit. */
163-
if (Py_FlushLine())
164-
PyErr_Clear();
248+
PyObject *f = PySys_GetObject("stdout");
249+
if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */
250+
PyErr_Clear();
165251
}
166252

167253
/* close everything

pythonforandroid/recipe.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,9 @@ def get_recipe_env(self, arch):
886886
env = super(CythonRecipe, self).get_recipe_env(arch)
887887
env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format(
888888
self.ctx.get_libs_dir(arch.arch) +
889-
' -L{} '.format(self.ctx.libs_dir)) + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2python3crystax/libs/armeabi '
889+
' -L{} '.format(self.ctx.libs_dir))
890+
if self.ctx.ndk_is_crystax:
891+
env['LDFLAGS'] = env['LDFLAGS'] + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2/libs/armeabi '
890892
if self.ctx.ndk_is_crystax:
891893
env['LDSHARED'] = env['CC'] + ' -shared'
892894
else:
@@ -902,6 +904,7 @@ def get_recipe_env(self, arch):
902904
env['LIBLINK_PATH'] = liblink_path
903905
ensure_dir(liblink_path)
904906

905-
env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS']
907+
if self.ctx.ndk_is_crystax:
908+
env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS']
906909

907910
return env

pythonforandroid/recipes/pyjnius/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
from pythonforandroid.toolchain import CythonRecipe, shprint, current_directory, info
3-
from pythonforandroid.patching import will_build
3+
from pythonforandroid.patching import will_build, check_any
44
import sh
55
from os.path import join
66

@@ -12,7 +12,7 @@ class PyjniusRecipe(CythonRecipe):
1212
depends = [('python2', 'python3crystax'), ('sdl2', 'sdl', 'sdl2python3crystax'), 'six']
1313
site_packages_name = 'jnius'
1414

15-
patches = [('sdl2_jnienv_getter.patch', will_build('sdl2python3crystax')),
15+
patches = [('sdl2_jnienv_getter.patch', check_any(will_build('sdl2python3crystax'), will_build('sdl2'))),
1616
'getenv.patch']
1717

1818
def postbuild_arch(self, arch):

0 commit comments

Comments
 (0)