From 428b3cac728cf77519284a32484d93299c0fd900 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 19 Dec 2015 21:01:50 +0000 Subject: [PATCH 01/43] Added temporary crystax bootstrap --- .../bootstraps/sdl2python3crystax/__init__.py | 88 +++++ .../build/AndroidManifest.xml | 45 +++ .../sdl2python3crystax/build/ant.properties | 17 + .../sdl2python3crystax/build/build.properties | 17 + .../sdl2python3crystax/build/build.py | 341 ++++++++++++++++++ .../sdl2python3crystax/build/build.xml | 93 +++++ .../sdl2python3crystax/build/jni/Android.mk | 1 + .../build/jni/Application.mk | 7 + .../build/proguard-project.txt | 20 + .../build/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 2683 bytes .../build/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 1698 bytes .../build/res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 3872 bytes .../build/res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 6874 bytes .../build/res/drawable/.gitkeep | 0 .../build/res/drawable/icon.png | Bin 0 -> 16525 bytes .../build/res/layout/main.xml | 13 + .../build/res/values/strings.xml | 5 + .../build/templates/AndroidManifest.xml.tmpl | 53 +++ .../build/templates/build.xml.tmpl | 93 +++++ .../build/templates/kivy-icon.png | Bin 0 -> 16525 bytes .../build/templates/strings.xml.tmpl | 5 + 21 files changed, 798 insertions(+) create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/__init__.py create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/AndroidManifest.xml create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/ant.properties create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/build.properties create mode 100755 pythonforandroid/bootstraps/sdl2python3crystax/build/build.py create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/build.xml create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Android.mk create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Application.mk create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/proguard-project.txt create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-hdpi/ic_launcher.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-mdpi/ic_launcher.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xhdpi/ic_launcher.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xxhdpi/ic_launcher.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/.gitkeep create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/icon.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/layout/main.xml create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/values/strings.xml create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/AndroidManifest.xml.tmpl create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/build.xml.tmpl create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/kivy-icon.png create mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/strings.xml.tmpl diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py b/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py new file mode 100644 index 0000000000..dfc2dc6cd1 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py @@ -0,0 +1,88 @@ +from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main +from os.path import join, exists +from os import walk +import glob +import sh + +class SDL2Bootstrap(Bootstrap): + name = 'sdl2python3crystax' + + recipe_depends = ['sdl2python3crystax', 'python3crystax'] + + can_be_chosen_automatically = False + + def run_distribute(self): + info_main('# Creating Android project from build and {} bootstrap'.format( + self.name)) + + info('This currently just copies the SDL2 build stuff straight from the build dir.') + shprint(sh.rm, '-rf', self.dist_dir) + shprint(sh.cp, '-r', self.build_dir, self.dist_dir) + with current_directory(self.dist_dir): + with open('local.properties', 'w') as fileh: + fileh.write('sdk.dir={}'.format(self.ctx.sdk_dir)) + + # AND: Hardcoding armeabi - naughty! + arch = ArchARM(self.ctx) + + with current_directory(self.dist_dir): + info('Copying python distribution') + + if not exists('private'): + shprint(sh.mkdir, 'private') + if not exists('assets'): + shprint(sh.mkdir, 'assets') + + hostpython = sh.Command(self.ctx.hostpython) + + # AND: The compileall doesn't work with python3, tries to import a wrong-arch lib + # shprint(hostpython, '-OO', '-m', 'compileall', join(self.ctx.build_dir, 'python-install')) + # if not exists('python-install'): + # shprint(sh.cp, '-a', join(self.ctx.build_dir, 'python-install'), '.') + + self.distribute_libs(arch, [self.ctx.libs_dir]) + self.distribute_aars(arch) + self.distribute_javaclasses(join(self.ctx.build_dir, 'java')) + + info('Filling private directory') + # if not exists(join('private', 'lib')): + # info('private/lib does not exist, making') + # shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') + # shprint(sh.mkdir, '-p', join('private', 'include', 'python3.4m')) + + # AND: Copylibs stuff should go here + # if exists(join('libs', 'armeabi', 'libpymodules.so')): + # shprint(sh.mv, join('libs', 'armeabi', 'libpymodules.so'), 'private/') + # shprint(sh.cp, join('python-install', 'include' , 'python3.4m', 'pyconfig.h'), join('private', 'include', 'python3.4m/')) + + # info('Removing some unwanted files') + # shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.4m.so')) + # shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.so')) + # shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) + + # with current_directory(join(self.dist_dir, 'private', 'lib', 'python3.4')): + # # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) + # removes = [] + # for dirname, something, filens in walk('.'): + # for filename in filens: + # for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): + # if filename.endswith(suffix): + # removes.append(filename) + # shprint(sh.rm, '-f', *removes) + + # info('Deleting some other stuff not used on android') + # # To quote the original distribute.sh, 'well...' + # # shprint(sh.rm, '-rf', 'ctypes') + # shprint(sh.rm, '-rf', 'lib2to3') + # shprint(sh.rm, '-rf', 'idlelib') + # for filename in glob.glob('config/libpython*.a'): + # shprint(sh.rm, '-f', filename) + # shprint(sh.rm, '-rf', 'config/python.o') + # # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') + # # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') + + + self.strip_libraries(arch) + super(SDL2Bootstrap, self).run_distribute() + +bootstrap = SDL2Bootstrap() diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/AndroidManifest.xml b/pythonforandroid/bootstraps/sdl2python3crystax/build/AndroidManifest.xml new file mode 100644 index 0000000000..a3dfc7b224 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/ant.properties b/pythonforandroid/bootstraps/sdl2python3crystax/build/ant.properties new file mode 100644 index 0000000000..b0971e891e --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/build.properties b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.properties new file mode 100644 index 0000000000..edc7f23050 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked in Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/build.py b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.py new file mode 100755 index 0000000000..3d0c46a9e7 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.py @@ -0,0 +1,341 @@ +#!/usr/bin/env python3 + +from __future__ import print_function + +from os.path import dirname, join, isfile, realpath, relpath, split +import os +import tarfile +import time +import subprocess +import shutil +from zipfile import ZipFile +import sys +import re + +from fnmatch import fnmatch + +import jinja2 + +if os.name == 'nt': + ANDROID = 'android.bat' + ANT = 'ant.bat' +else: + ANDROID = 'android' + ANT = 'ant' + +curdir = dirname(__file__) + +# Try to find a host version of Python that matches our ARM version. +# PYTHON = join(curdir, 'python-install', 'bin', 'python.host') + +BLACKLIST_PATTERNS = [ + # code versionning + '^*.hg/*', + '^*.git/*', + '^*.bzr/*', + '^*.svn/*', + + # pyc/py + '*.pyc', + # '*.py', # AND: Need to fix this to add it back + + # temp files + '~', + '*.bak', + '*.swp', +] + +WHITELIST_PATTERNS = [] + +python_files = [] + + +environment = jinja2.Environment(loader=jinja2.FileSystemLoader( + join(curdir, 'templates'))) + +def render(template, dest, **kwargs): + '''Using jinja2, render `template` to the filename `dest`, supplying the + + keyword arguments as template parameters. + ''' + + template = environment.get_template(template) + text = template.render(**kwargs) + + f = open(dest, 'wb') + f.write(text.encode('utf-8')) + f.close() + + +def is_whitelist(name): + return match_filename(WHITELIST_PATTERNS, name) + + +def is_blacklist(name): + if is_whitelist(name): + return False + return match_filename(BLACKLIST_PATTERNS, name) + + +def match_filename(pattern_list, name): + for pattern in pattern_list: + if pattern.startswith('^'): + pattern = pattern[1:] + else: + pattern = '*/' + pattern + if fnmatch(name, pattern): + return True + + +def listfiles(d): + basedir = d + subdirlist = [] + for item in os.listdir(d): + fn = join(d, item) + if isfile(fn): + yield fn + else: + subdirlist.append(os.path.join(basedir, item)) + for subdir in subdirlist: + for fn in listfiles(subdir): + yield fn + +def make_python_zip(): + ''' + Search for all the python related files, and construct the pythonXX.zip + According to + # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html + site-packages, config and lib-dynload will be not included. + ''' + return + global python_files + d = realpath(join('private', 'lib', 'python3.4')) + + + def select(fn): + if is_blacklist(fn): + return False + fn = realpath(fn) + assert(fn.startswith(d)) + fn = fn[len(d):] + if (fn.startswith('/site-packages/') or + fn.startswith('/config/') or + fn.startswith('/lib-dynload/') or + fn.startswith('/libpymodules.so')): + return False + return fn + + # get a list of all python file + python_files = [x for x in listfiles(d) if select(x)] + + # create the final zipfile + zfn = join('private', 'lib', 'python34.zip') + zf = ZipFile(zfn, 'w') + + # put all the python files in it + for fn in python_files: + afn = fn[len(d):] + zf.write(fn, afn) + zf.close() + +def make_tar(tfn, source_dirs, ignore_path=[]): + ''' + Make a zip file `fn` from the contents of source_dis. + ''' + + # selector function + def select(fn): + rfn = realpath(fn) + for p in ignore_path: + if p.endswith('/'): + p = p[:-1] + if rfn.startswith(p): + return False + if rfn in python_files: + return False + return not is_blacklist(fn) + + # get the files and relpath file of all the directory we asked for + files = [] + for sd in source_dirs: + sd = realpath(sd) + compile_dir(sd) + files += [(x, relpath(realpath(x), sd)) for x in listfiles(sd) + if select(x)] + + # create tar.gz of thoses files + tf = tarfile.open(tfn, 'w:gz', format=tarfile.USTAR_FORMAT) + dirs = [] + for fn, afn in files: + print('%s: %s' % (tfn, fn)) + dn = dirname(afn) + if dn not in dirs: + # create every dirs first if not exist yet + d = '' + for component in split(dn): + d = join(d, component) + if d.startswith('/'): + d = d[1:] + if d == '' or d in dirs: + continue + dirs.append(d) + tinfo = tarfile.TarInfo(d) + tinfo.type = tarfile.DIRTYPE + tf.addfile(tinfo) + + # put the file + tf.add(fn, afn) + tf.close() + + +def compile_dir(dfn): + ''' + Compile *.py in directory `dfn` to *.pyo + ''' + + return # AND: Currently leaving out the compile to pyo step because it's somehow broken + # -OO = strip docstrings + # subprocess.call([PYTHON, '-OO', '-m', 'compileall', '-f', dfn]) + + +def make_package(args): + url_scheme = 'kivy' + + # Figure out versions of the private and public data. + private_version = str(time.time()) + + # # Update the project to a recent version. + # try: + # subprocess.call([ANDROID, 'update', 'project', '-p', '.', '-t', + # 'android-{}'.format(args.sdk_version)]) + # except (OSError, IOError): + # print('An error occured while calling', ANDROID, 'update') + # print('Your PATH must include android tools.') + # sys.exit(-1) + + # Delete the old assets. + if os.path.exists('assets/public.mp3'): + os.unlink('assets/public.mp3') + + if os.path.exists('assets/private.mp3'): + os.unlink('assets/private.mp3') + + # In order to speedup import and initial depack, + # construct a python34.zip + make_python_zip() + + # Package up the private and public data. + # AND: Just private for now + if args.private: + make_tar('assets/private.mp3', ['private', args.private], args.ignore_path) + # else: + # make_tar('assets/private.mp3', ['private']) + + # if args.dir: + # make_tar('assets/public.mp3', [args.dir], args.ignore_path) + + + # # Build. + # try: + # for arg in args.command: + # subprocess.check_call([ANT, arg]) + # except (OSError, IOError): + # print 'An error occured while calling', ANT + # print 'Did you install ant on your system ?' + # sys.exit(-1) + + + # Prepare some variables for templating process + + default_icon = 'templates/kivy-icon.png' + shutil.copy(args.icon or default_icon, 'res/drawable/icon.png') + + versioned_name = (args.name.replace(' ', '').replace('\'', '') + + '-' + args.version) + + version_code = 0 + if not args.numeric_version: + for i in args.version.split('.'): + version_code *= 100 + version_code += int(i) + args.numeric_version = str(version_code) + + render( + 'AndroidManifest.xml.tmpl', + 'AndroidManifest.xml', + args=args, + ) + + render( + 'build.xml.tmpl', + 'build.xml', + args=args, + versioned_name=versioned_name) + + render( + 'strings.xml.tmpl', + 'res/values/strings.xml', + args=args) + + with open(join(dirname(__file__), 'res', + 'values', 'strings.xml')) as fileh: + lines = fileh.read() + + with open(join(dirname(__file__), 'res', + 'values', 'strings.xml'), 'w') as fileh: + fileh.write(re.sub(r'"private_version">[0-9\.]*<', + '"private_version">{}<'.format( + str(time.time())), lines)) + + +def parse_args(args=None): + import argparse + ap = argparse.ArgumentParser(description='''\ +Package a Python application for Android. + +For this to work, Java and Ant need to be in your path, as does the +tools directory of the Android SDK. +''') + + ap.add_argument('--private', dest='private', + help='the dir of user files', + required=True) + ap.add_argument('--package', dest='package', + help=('The name of the java package the project will be' + ' packaged under.'), + required=True) + ap.add_argument('--name', dest='name', + help=('The human-readable name of the project.'), + required=True) + ap.add_argument('--numeric-version', dest='numeric_version', + help=('The numeric version number of the project. If not ' + 'given, this is automatically computed from the ' + 'version.')) + ap.add_argument('--version', dest='version', + help=('The version number of the project. This should ' + 'consist of numbers and dots, and should have the ' + 'same number of groups of numbers as previous ' + 'versions.'), + required=True) + ap.add_argument('--orientation', dest='orientation', default='portrait', + help=('The orientation that the game will display in. ' + 'Usually one of "landscape", "portrait" or ' + '"sensor"')) + ap.add_argument('--icon', dest='icon', + help='A png file to use as the icon for the application.') + ap.add_argument('--permission', dest='permissions', action='append', + help='The permissions to give this app.') + + if args is None: + args = sys.argv[1:] + args = ap.parse_args(args) + args.ignore_path = [] + + if args.permissions is None: + args.permissions = [] + + make_package(args) + +if __name__ == "__main__": + + parse_args() diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/build.xml b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.xml new file mode 100644 index 0000000000..9f19a077b1 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/build.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Android.mk b/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Android.mk new file mode 100644 index 0000000000..5053e7d643 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Application.mk b/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Application.mk new file mode 100644 index 0000000000..e79e378f94 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Application.mk @@ -0,0 +1,7 @@ + +# Uncomment this if you're using STL in your project +# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information +# APP_STL := stlport_static + +# APP_ABI := armeabi armeabi-v7a x86 +APP_ABI := $(ARCH) diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/proguard-project.txt b/pythonforandroid/bootstraps/sdl2python3crystax/build/proguard-project.txt new file mode 100644 index 0000000000..f2fe1559a2 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-hdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d50bdaae06ee5a8d3f39911f81715abd3bf7b24d GIT binary patch literal 2683 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 literal 0 HcmV?d00001 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-mdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..0a299eb3cc0273ad1fc260cf0b4a2c35f5d373f5 GIT binary patch literal 1698 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 literal 0 HcmV?d00001 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xxhdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d423dac2624cf0b5dc90821a15362bc29e5a1e6b GIT binary patch literal 6874 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 literal 0 HcmV?d00001 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/.gitkeep b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/icon.png b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59a00ba6fff07cec43a4100fdf22f3f679df2349 GIT binary patch literal 16525 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 L>T(q_W}*KFob!<> literal 0 HcmV?d00001 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/layout/main.xml b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/layout/main.xml new file mode 100644 index 0000000000..123c4b6eac --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/layout/main.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/res/values/strings.xml b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/values/strings.xml new file mode 100644 index 0000000000..daebceb9d5 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/res/values/strings.xml @@ -0,0 +1,5 @@ + + + SDL App + 0.1 + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/AndroidManifest.xml.tmpl b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/AndroidManifest.xml.tmpl new file mode 100644 index 0000000000..75e3d62fa8 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/AndroidManifest.xml.tmpl @@ -0,0 +1,53 @@ + + + + + + + + + + + + + {% for perm in args.permissions %} + {% if '.' in perm %} + + {% else %} + + {% endif %} + {% endfor %} + + + + + + + + + + + + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/build.xml.tmpl b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/build.xml.tmpl new file mode 100644 index 0000000000..9564aae306 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/build.xml.tmpl @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/kivy-icon.png b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/kivy-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..59a00ba6fff07cec43a4100fdf22f3f679df2349 GIT binary patch literal 16525 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 L>T(q_W}*KFob!<> literal 0 HcmV?d00001 diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/strings.xml.tmpl b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/strings.xml.tmpl new file mode 100644 index 0000000000..0bbeb192f7 --- /dev/null +++ b/pythonforandroid/bootstraps/sdl2python3crystax/build/templates/strings.xml.tmpl @@ -0,0 +1,5 @@ + + + {{ args.name }} + 0.1 + From aea6dbd6b1e93b8846cad0040bc45375faa52eb0 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 19 Dec 2015 21:03:12 +0000 Subject: [PATCH 02/43] Added temporary crystax recipes --- pythonforandroid/build.py | 4 + pythonforandroid/recipes/python3/__init__.py | 4 + .../recipes/python3crystax/__init__.py | 25 + .../recipes/python3crystax/log_failures.patch | 385 ++++++++++++ .../patches-termux/Lib-tmpfile.py.patch | 12 + .../patches-termux/_cursesmodule.c.patch | 15 + .../patches-termux/dlfcn_py_android.patch | 30 + .../patches-termux/mathmodule.c.patch | 47 ++ .../patches-termux/posixmodule.c.patch | 100 +++ .../pwdmodule_no_pw_gecos.patch | 16 + .../patches-termux/setup.py.patch | 23 + .../patches-termux/subprocess.py.patch | 12 + .../python-3.4.2-android-libmpdec.patch | 158 +++++ .../patches/python-3.4.2-android-locale.patch | 255 ++++++++ .../patches/python-3.4.2-android-misc.patch | 313 ++++++++++ ...ndroid-missing-getdents64-definition.patch | 17 + .../patches/python-3.4.2-cross-compile.patch | 78 +++ .../python-3.4.2-libpymodules_loader.patch | 42 ++ .../patches/python-3.4.2-python-misc.patch | 86 +++ .../python-3.5.0-android-locale.patch | 573 +++++++++++++++++ .../python-3.5.0-android-misc.patch | 573 +++++++++++++++++ .../python-3.5.0-define_macro.patch | 13 + ...python-3.5.0-locale_and_android_misc.patch | 586 ++++++++++++++++++ .../recipes/sdl2python3/__init__.py | 2 +- .../recipes/sdl2python3crystax/__init__.py | 31 + .../sdl2python3crystax/add_nativeSetEnv.patch | 24 + 26 files changed, 3423 insertions(+), 1 deletion(-) create mode 100644 pythonforandroid/recipes/python3crystax/__init__.py create mode 100644 pythonforandroid/recipes/python3crystax/log_failures.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-misc.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-define_macro.patch create mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-locale_and_android_misc.patch create mode 100644 pythonforandroid/recipes/sdl2python3crystax/__init__.py create mode 100644 pythonforandroid/recipes/sdl2python3crystax/add_nativeSetEnv.patch diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py index 56333e54ef..8cf6f1f20b 100644 --- a/pythonforandroid/build.py +++ b/pythonforandroid/build.py @@ -126,6 +126,10 @@ def ndk_ver(self): def ndk_ver(self, value): self._ndk_ver = value + @property + def ndk_is_crystax(self): + return True if self.ndk_ver[:7] == 'crystax' else False + @property def sdk_dir(self): '''The path to the Android SDK.''' diff --git a/pythonforandroid/recipes/python3/__init__.py b/pythonforandroid/recipes/python3/__init__.py index 20441d0120..ba589274dd 100644 --- a/pythonforandroid/recipes/python3/__init__.py +++ b/pythonforandroid/recipes/python3/__init__.py @@ -13,6 +13,10 @@ class Python3Recipe(Recipe): depends = ['hostpython3'] conflicts = ['python2'] + def __init__(self, **kwargs): + super(Python3Recipe, self).__init__(**kwargs) + self.crystax = lambda *args: True if self.ctx.ndk_is_crystax else False + def prebuild_arch(self, arch): build_dir = self.get_build_container_dir(arch.arch) if exists(join(build_dir, '.patched')): diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py new file mode 100644 index 0000000000..35c7612841 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -0,0 +1,25 @@ + +from pythonforandroid.toolchain import Recipe, shprint, current_directory, ArchARM +from pythonforandroid.logger import info +from os.path import exists, join +from os import uname +import glob +import sh + +class Python3Recipe(Recipe): + version = '' + url = '' + name = 'python3crystax' + + depends = ['hostpython3'] + conflicts = ['python2', 'python3'] + + def __init__(self, **kwargs): + super(Python3Recipe, self).__init__(**kwargs) + self.crystax = lambda *args: True if self.ctx.ndk_is_crystax else False + + def build_arch(self, arch): + info('doing nothing, the crystax python3 is included in the ndk!') + + +recipe = Python3Recipe() diff --git a/pythonforandroid/recipes/python3crystax/log_failures.patch b/pythonforandroid/recipes/python3crystax/log_failures.patch new file mode 100644 index 0000000000..ec85035515 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/log_failures.patch @@ -0,0 +1,385 @@ +diff --git a/Include/Python.h b/Include/Python.h +index 2dd8290..aab5810 100644 +--- a/Include/Python.h ++++ b/Include/Python.h +@@ -41,6 +41,12 @@ + #include + #endif + ++/* p4a log redirect */ ++#include ++#include "android/log.h" ++#define LOG(x) __android_log_write(ANDROID_LOG_INFO, "python", (x)) ++ ++ + /* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. +diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c +index 9bb3666..4fb89c5 100644 +--- a/Modules/gcmodule.c ++++ b/Modules/gcmodule.c +@@ -1758,13 +1758,14 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) + PyVarObject *op; + + if (nitems < 0) { ++ LOG("PyErr_BadInternalCall in gc"); + PyErr_BadInternalCall(); + return NULL; + } + size = _PyObject_VAR_SIZE(tp, nitems); + op = (PyVarObject *) _PyObject_GC_Malloc(size); + if (op != NULL) +- op = PyObject_INIT_VAR(op, tp, nitems); ++ op = PyObject_INIT_VAR(op, tp, nitems); + return op; + } + +diff --git a/Modules/getpath.c b/Modules/getpath.c +index c057737..5d02f08 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -866,6 +866,7 @@ wchar_t * + Py_GetProgramFullPath(void) + { + if (!module_search_path) ++ LOG("Py_GetProgramFullPath: calculating path"); + calculate_path(); + return progpath; + } +diff --git a/Objects/floatobject.c b/Objects/floatobject.c +index 05b7679..be38e75 100644 +--- a/Objects/floatobject.c ++++ b/Objects/floatobject.c +@@ -77,6 +77,7 @@ PyFloat_GetInfo(void) + + floatinfo = PyStructSequence_New(&FloatInfoType); + if (floatinfo == NULL) { ++ LOG("PyFloat_GetInfo got NULL"); + return NULL; + } + +@@ -84,22 +85,63 @@ PyFloat_GetInfo(void) + PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag)) + #define SetDblFlag(flag) \ + PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag)) ++ ++ LOG("About to start typing to set int and dbl flags"); ++ if (PyErr_Occurred()) { ++ LOG("err even before 1!"); ++ } else { ++ LOG("no err before this"); ++ } + + SetDblFlag(DBL_MAX); ++ if (PyErr_Occurred()) { ++ LOG("err 1"); ++ } + SetIntFlag(DBL_MAX_EXP); ++ if (PyErr_Occurred()) { ++ LOG("err 2"); ++ } + SetIntFlag(DBL_MAX_10_EXP); ++ if (PyErr_Occurred()) { ++ LOG("err 3"); ++ } + SetDblFlag(DBL_MIN); ++ if (PyErr_Occurred()) { ++ LOG("err 4"); ++ } + SetIntFlag(DBL_MIN_EXP); ++ if (PyErr_Occurred()) { ++ LOG("err 5"); ++ } + SetIntFlag(DBL_MIN_10_EXP); ++ if (PyErr_Occurred()) { ++ LOG("err 6"); ++ } + SetIntFlag(DBL_DIG); ++ if (PyErr_Occurred()) { ++ LOG("err 7"); ++ } + SetIntFlag(DBL_MANT_DIG); ++ if (PyErr_Occurred()) { ++ LOG("err 8"); ++ } + SetDblFlag(DBL_EPSILON); ++ if (PyErr_Occurred()) { ++ LOG("err 9"); ++ } + SetIntFlag(FLT_RADIX); ++ if (PyErr_Occurred()) { ++ LOG("err 10"); ++ } + SetIntFlag(FLT_ROUNDS); ++ if (PyErr_Occurred()) { ++ LOG("err 11"); ++ } + #undef SetIntFlag + #undef SetDblFlag + + if (PyErr_Occurred()) { ++ LOG("PyErr_Occurred in floatinfo stuff"); + Py_CLEAR(floatinfo); + return NULL; + } +diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c +index d9c131c..0840930 100644 +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -2297,6 +2297,12 @@ PyUnicode_AsUCS4Copy(PyObject *string) + PyObject * + PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) + { ++ if (PyErr_Occurred()) { ++ LOG("PyErr already occurred before PyUnicode_FromWideChar does anything"); ++ } else { ++ LOG("start of PyUnicode_FromWideChar; everything seems fine"); ++ } ++ + if (w == NULL) { + if (size == 0) + _Py_RETURN_UNICODE_EMPTY(); +diff --git a/Python/errors.c b/Python/errors.c +index 996292a..20bc3f1 100644 +--- a/Python/errors.c ++++ b/Python/errors.c +@@ -755,6 +755,9 @@ PyErr_Format(PyObject *exception, const char *format, ...) + { + va_list vargs; + PyObject* string; ++ ++ LOG("PyErr Format with:"); ++ LOG(format); + + #ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +diff --git a/Python/pythonrun.c b/Python/pythonrun.c +index 0327830..e4428d0 100644 +--- a/Python/pythonrun.c ++++ b/Python/pythonrun.c +@@ -415,6 +415,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) + /* initialize builtin exceptions */ + _PyExc_Init(bimod); + ++ LOG("Got to _PySys_Init"); + sysmod = _PySys_Init(); + if (sysmod == NULL) + Py_FatalError("Py_Initialize: can't initialize sys"); +@@ -2594,6 +2595,8 @@ Py_FatalError(const char *msg) + { + const int fd = fileno(stderr); + PyThreadState *tstate; ++ ++ LOG(msg); + + fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ +diff --git a/Python/sysmodule.c b/Python/sysmodule.c +index 39fe53f..d76c793 100644 +--- a/Python/sysmodule.c ++++ b/Python/sysmodule.c +@@ -1633,27 +1633,36 @@ _PySys_Init(void) + int res; + + m = PyModule_Create(&sysmodule); +- if (m == NULL) ++ if (m == NULL) { ++ LOG("module create is NULL"); + return NULL; ++ } + sysdict = PyModule_GetDict(m); + #define SET_SYS_FROM_STRING_BORROW(key, value) \ + do { \ + PyObject *v = (value); \ +- if (v == NULL) \ ++ if (v == NULL) { \ ++ LOG("set from string 1 is NULL"); \ + return NULL; \ ++ } \ + res = PyDict_SetItemString(sysdict, key, v); \ + if (res < 0) { \ ++ LOG("_SetItemString thing was NULL"); \ + return NULL; \ + } \ + } while (0) + #define SET_SYS_FROM_STRING(key, value) \ + do { \ + PyObject *v = (value); \ +- if (v == NULL) \ ++ if (v == NULL) { \ ++ LOG("set from string 2 is NULL"); \ ++ LOG(key); \ + return NULL; \ ++ } \ + res = PyDict_SetItemString(sysdict, key, v); \ + Py_DECREF(v); \ + if (res < 0) { \ ++ LOG("_SetItemString 2 thing was NULL"); \ + return NULL; \ + } \ + } while (0) +@@ -1677,47 +1686,102 @@ _PySys_Init(void) + #endif + + /* stdin/stdout/stderr are now set by pythonrun.c */ ++ ++ if (PyErr_Occurred()) { ++ LOG("PyErr_Occurred before set_sys_from_string stuff"); ++ } else { ++ LOG("PyErr has *NOT* yet occurred before set_sys_from_string stuff"); ++ } + + SET_SYS_FROM_STRING_BORROW("__displayhook__", + PyDict_GetItemString(sysdict, "displayhook")); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after __displayhook__"); ++ } + SET_SYS_FROM_STRING_BORROW("__excepthook__", + PyDict_GetItemString(sysdict, "excepthook")); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after __excepthook__"); ++ } + SET_SYS_FROM_STRING("version", + PyUnicode_FromString(Py_GetVersion())); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after __excepthook__"); ++ } + SET_SYS_FROM_STRING("hexversion", + PyLong_FromLong(PY_VERSION_HEX)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after hexversion"); ++ } + SET_SYS_FROM_STRING("_mercurial", + Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), + _Py_hgversion())); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after _mercurial"); ++ } + SET_SYS_FROM_STRING("dont_write_bytecode", + PyBool_FromLong(Py_DontWriteBytecodeFlag)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after dont_write_bytecode"); ++ } + SET_SYS_FROM_STRING("api_version", + PyLong_FromLong(PYTHON_API_VERSION)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after api_version"); ++ } + SET_SYS_FROM_STRING("copyright", + PyUnicode_FromString(Py_GetCopyright())); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after copyright"); ++ } + SET_SYS_FROM_STRING("platform", + PyUnicode_FromString(Py_GetPlatform())); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after platform"); ++ } else { ++ LOG("No PyErr yet, about to do executable"); ++ } + SET_SYS_FROM_STRING("executable", + PyUnicode_FromWideChar( + Py_GetProgramFullPath(), -1)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after executable"); ++ } + SET_SYS_FROM_STRING("prefix", + PyUnicode_FromWideChar(Py_GetPrefix(), -1)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after prefix"); ++ } + SET_SYS_FROM_STRING("exec_prefix", + PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after exec_prefix"); ++ } + SET_SYS_FROM_STRING("base_prefix", + PyUnicode_FromWideChar(Py_GetPrefix(), -1)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after base_prefix"); ++ } + SET_SYS_FROM_STRING("base_exec_prefix", + PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr after base_exec_prefix"); ++ } + SET_SYS_FROM_STRING("maxsize", + PyLong_FromSsize_t(PY_SSIZE_T_MAX)); ++ if (PyErr_Occurred()) { ++ LOG("PyErr_Occurred before float_info stuff"); ++ } + SET_SYS_FROM_STRING("float_info", + PyFloat_GetInfo()); + SET_SYS_FROM_STRING("int_info", + PyLong_GetInfo()); + /* initialize hash_info */ + if (Hash_InfoType.tp_name == NULL) { +- if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) ++ if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { ++ LOG("InitType2 thing was NULL"); + return NULL; ++ } + } + SET_SYS_FROM_STRING("hash_info", + get_hash_info()); +@@ -1745,8 +1809,10 @@ _PySys_Init(void) + #endif + if (warnoptions == NULL) { + warnoptions = PyList_New(0); +- if (warnoptions == NULL) ++ if (warnoptions == NULL) { ++ LOG("warnoptions is NULL"); + return NULL; ++ } + } + else { + Py_INCREF(warnoptions); +@@ -1758,8 +1824,10 @@ _PySys_Init(void) + /* version_info */ + if (VersionInfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&VersionInfoType, +- &version_info_desc) < 0) ++ &version_info_desc) < 0) { ++ LOG("versioninfo stuff is NULL"); + return NULL; ++ } + } + version_info = make_version_info(); + SET_SYS_FROM_STRING("version_info", version_info); +@@ -1775,8 +1843,10 @@ _PySys_Init(void) + + /* flags */ + if (FlagsType.tp_name == 0) { +- if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) ++ if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) { ++ LOG("flags stuff is NULL"); + return NULL; ++ } + } + SET_SYS_FROM_STRING("flags", make_flags()); + /* prevent user from creating new instances */ +@@ -1790,8 +1860,10 @@ _PySys_Init(void) + /* getwindowsversion */ + if (WindowsVersionType.tp_name == 0) + if (PyStructSequence_InitType2(&WindowsVersionType, +- &windows_version_desc) < 0) ++ &windows_version_desc) < 0) { ++ LOG("Windows version is NULL"); + return NULL; ++ } + /* prevent user from creating new instances */ + WindowsVersionType.tp_init = NULL; + WindowsVersionType.tp_new = NULL; +@@ -1815,8 +1887,10 @@ _PySys_Init(void) + + #undef SET_SYS_FROM_STRING + #undef SET_SYS_FROM_STRING_BORROW +- if (PyErr_Occurred()) ++if (PyErr_Occurred()) { ++ LOG("PyErr_Occurred to NULL"); + return NULL; ++ } + return m; + } + diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch new file mode 100644 index 0000000000..ec6a2e80cf --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch @@ -0,0 +1,12 @@ +diff -u -r ../Python-3.4.3/Lib/tempfile.py ./Lib/tempfile.py +--- ../Python-3.4.3/Lib/tempfile.py 2015-02-25 06:27:44.000000000 -0500 ++++ ./Lib/tempfile.py 2015-07-21 19:58:07.631659902 -0400 +@@ -124,7 +124,7 @@ + if _os.name == 'nt': + dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) + else: +- dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) ++ dirlist.extend([ '@TERMUX_PREFIX@/tmp' ]) + + # As a last resort, the current directory. + try: diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch new file mode 100644 index 0000000000..b4740fd2b8 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch @@ -0,0 +1,15 @@ +We use libandroid-support when building Python, but Python does not +use LDFLAGS when building modules (and not much point in this case). + +diff -u -r ../Python-3.4.1/Modules/_cursesmodule.c ./Modules/_cursesmodule.c +--- ../Python-3.4.1/Modules/_cursesmodule.c 2014-05-19 07:19:39.000000000 +0200 ++++ ./Modules/_cursesmodule.c 2014-06-04 08:56:50.441097925 +0200 +@@ -121,7 +121,7 @@ + #include + #endif + +-#ifdef HAVE_LANGINFO_H ++#if defined(HAVE_LANGINFO_H) && !defined(__ANDROID__) + #include + #endif + diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch b/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch new file mode 100644 index 0000000000..ea5992bf8f --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch @@ -0,0 +1,30 @@ +From https://github.com/kivy/python-for-android/blob/master/recipes/python/patches/fix-dlfcn.patch + +See https://github.com/kivy/python-for-android/issues/141 +diff -u -r ../Python-3.4.0rc1/Lib/plat-linux/DLFCN.py ./Lib/plat-linux/DLFCN.py +--- ../Python-3.4.0rc1/Lib/plat-linux/DLFCN.py 2014-02-10 23:51:49.000000000 +0100 ++++ ./Lib/plat-linux/DLFCN.py 2014-02-13 03:25:19.000000000 +0100 +@@ -74,10 +74,18 @@ + # Included from gnu/stubs.h + + # Included from bits/dlfcn.h ++ ++# PATCHED FOR ANDROID (the only supported symbols are): ++# enum { ++# RTLD_NOW = 0, ++# RTLD_LAZY = 1, ++# RTLD_LOCAL = 0, ++# RTLD_GLOBAL = 2, ++# }; + RTLD_LAZY = 0x00001 +-RTLD_NOW = 0x00002 +-RTLD_BINDING_MASK = 0x3 +-RTLD_NOLOAD = 0x00004 +-RTLD_GLOBAL = 0x00100 ++RTLD_NOW = 0x00000 ++RTLD_BINDING_MASK = 0x0 ++RTLD_NOLOAD = 0x00000 ++RTLD_GLOBAL = 0x00002 + RTLD_LOCAL = 0 +-RTLD_NODELETE = 0x01000 ++RTLD_NODELETE = 0x00000 diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch new file mode 100644 index 0000000000..7f611409b4 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch @@ -0,0 +1,47 @@ +The math module uses function pointers to math functions, which breaks +using the system libm on ARM since we compile with -mhard-float. + +diff -u -r ../Python-3.4.3/Modules/mathmodule.c ./Modules/mathmodule.c +--- ../Python-3.4.3/Modules/mathmodule.c 2015-02-25 06:27:46.000000000 -0500 ++++ ./Modules/mathmodule.c 2015-04-29 16:50:52.895371496 -0400 +@@ -727,7 +727,7 @@ + */ + + static PyObject * +-math_1_to_whatever(PyObject *arg, double (*func) (double), ++math_1_to_whatever(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), + PyObject *(*from_double_func) (double), + int can_overflow) + { +@@ -765,7 +765,7 @@ + errno = ERANGE for overflow). */ + + static PyObject * +-math_1a(PyObject *arg, double (*func) (double)) ++math_1a(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double)) + { + double x, r; + x = PyFloat_AsDouble(arg); +@@ -808,19 +808,19 @@ + */ + + static PyObject * +-math_1(PyObject *arg, double (*func) (double), int can_overflow) ++math_1(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), int can_overflow) + { + return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); + } + + static PyObject * +-math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) ++math_1_to_int(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), int can_overflow) + { + return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); + } + + static PyObject * +-math_2(PyObject *args, double (*func) (double, double), char *funcname) ++math_2(PyObject *args, __NDK_FPABI_MATH__ double (*func) (double, double), char *funcname) + { + PyObject *ox, *oy; + double x, y, r; diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch new file mode 100644 index 0000000000..ff00333301 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch @@ -0,0 +1,100 @@ +diff -u -r ../Python-3.4.1/Modules/posixmodule.c ./Modules/posixmodule.c +--- ../Python-3.4.1/Modules/posixmodule.c 2014-05-19 07:19:39.000000000 +0200 ++++ ./Modules/posixmodule.c 2014-06-25 21:42:11.191524129 +0200 +@@ -6048,7 +6048,7 @@ + if (_Py_set_inheritable(master_fd, 0, NULL) < 0) + goto posix_error; + +-#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) ++#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) && !defined(__ANDROID__) + ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ + ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ + #ifndef __hpux +@@ -9162,7 +9162,12 @@ + needed definitions in sys/statvfs.h */ + #define _SVID3 + #endif +-#include ++#ifdef __ANDROID__ ++# include ++# define statvfs statfs ++#else ++# include ++#endif + + static PyObject* + _pystatvfs_fromstructstatvfs(struct statvfs st) { +@@ -9178,9 +9183,15 @@ + PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); ++#ifdef __ANDROID__ ++ PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_bavail)); ++ PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flags)); ++ PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namelen)); ++#else + PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); ++#endif + #else + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); +@@ -9194,11 +9205,18 @@ + PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, + PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); ++#ifdef __ANDROID__ ++ PyStructSequence_SET_ITEM(v, 7, ++ PyLong_FromLongLong((PY_LONG_LONG) st.b_favail)); ++ PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flags)); ++ PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namelen)); ++#else + PyStructSequence_SET_ITEM(v, 7, + PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); + #endif ++#endif + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; +@@ -9221,7 +9239,11 @@ + if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) + return NULL; + Py_BEGIN_ALLOW_THREADS ++#ifdef __ANDROID__ ++ res = fstatfs(fd, &st); ++#else + res = fstatvfs(fd, &st); ++#endif + Py_END_ALLOW_THREADS + if (res != 0) + return posix_error(); +@@ -9232,7 +9254,13 @@ + + + #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) +-#include ++#ifdef __ANDROID__ ++# include ++# define statvfs statfs ++#else ++# include ++#endif ++ + + PyDoc_STRVAR(posix_statvfs__doc__, + "statvfs(path)\n\n\ +@@ -9271,7 +9299,11 @@ + goto exit; + } + #endif ++#ifdef __ANDROID__ ++ result = fstatfs(path.fd, &st); ++#else + result = fstatvfs(path.fd, &st); ++#endif + } + else + #endif diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch b/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch new file mode 100644 index 0000000000..4e4f44159b --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch @@ -0,0 +1,16 @@ +diff -u -r ../Python-3.4.0rc1/Modules/pwdmodule.c ./Modules/pwdmodule.c +--- ../Python-3.4.0rc1/Modules/pwdmodule.c 2014-02-10 23:51:50.000000000 +0100 ++++ ./Modules/pwdmodule.c 2014-02-13 02:16:12.000000000 +0100 +@@ -72,7 +72,12 @@ + SETS(setIndex++, p->pw_passwd); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); ++#ifdef __ANDROID__ ++ SETS(setIndex++, Py_None); ++ Py_INCREF(Py_None); ++#else + SETS(setIndex++, p->pw_gecos); ++#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch new file mode 100644 index 0000000000..ed32d444b6 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch @@ -0,0 +1,23 @@ +diff -u -r ../Python-3.4.1/setup.py ./setup.py +--- ../Python-3.4.1/setup.py 2014-05-19 07:19:40.000000000 +0200 ++++ ./setup.py 2014-06-04 11:12:26.776875501 +0200 +@@ -568,7 +568,8 @@ + libraries=math_libs) ) + + # time libraries: librt may be needed for clock_gettime() +- time_libs = [] ++ # math_libs is needed by floatsleep() ++ time_libs = list(math_libs) + lib = sysconfig.get_config_var('TIMEMODULE_LIB') + if lib: + time_libs.append(lib) +@@ -625,7 +626,8 @@ + missing.append('spwd') + + # select(2); not on ancient System V +- exts.append( Extension('select', ['selectmodule.c']) ) ++ # selectmodule.c calls the ceil(3) math function ++ exts.append( Extension('select', ['selectmodule.c'], libraries=math_libs) ) + + # Fred Drake's interface to the Python parser + exts.append( Extension('parser', ['parsermodule.c']) ) diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch new file mode 100644 index 0000000000..41d399ae74 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch @@ -0,0 +1,12 @@ +diff -u -r ../Python-3.4.1/Lib/subprocess.py ./Lib/subprocess.py +--- ../Python-3.4.1/Lib/subprocess.py 2014-05-19 07:19:38.000000000 +0200 ++++ ./Lib/subprocess.py 2014-06-04 11:31:48.708843737 +0200 +@@ -1344,7 +1344,7 @@ + args = list(args) + + if shell: +- args = ["/bin/sh", "-c"] + args ++ args = ["/system/bin/sh", "-c"] + args + if executable: + args[0] = executable + diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch new file mode 100644 index 0000000000..66ccf0870c --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch @@ -0,0 +1,158 @@ +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/basearith.c Python-3.3.5-android/Modules/_decimal/libmpdec/basearith.c +--- Python-3.3.5/Modules/_decimal/libmpdec/basearith.c 2014-03-09 09:40:25.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/basearith.c 2014-08-05 16:11:29.000000000 +0200 +@@ -32,7 +32,7 @@ + #include + #include + #include "constants.h" +-#include "memory.h" ++#include "mpmemory.h" + #include "typearith.h" + #include "basearith.h" + +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/io.c Python-3.3.5-android/Modules/_decimal/libmpdec/io.c +--- Python-3.3.5/Modules/_decimal/libmpdec/io.c 2014-08-05 16:05:22.000000000 +0200 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/io.c 2014-08-05 16:11:42.000000000 +0200 +@@ -37,7 +37,7 @@ + #include + #include "bits.h" + #include "constants.h" +-#include "memory.h" ++#include "mpmemory.h" + #include "typearith.h" + #include "io.h" + +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/memory.c Python-3.3.5-android/Modules/_decimal/libmpdec/memory.c +--- Python-3.3.5/Modules/_decimal/libmpdec/memory.c 2014-03-09 09:40:25.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/memory.c 2014-08-05 16:11:52.000000000 +0200 +@@ -30,7 +30,7 @@ + #include + #include + #include "typearith.h" +-#include "memory.h" ++#include "mpmemory.h" + + + /* Guaranteed minimum allocation for a coefficient. May be changed once +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/memory.h Python-3.3.5-android/Modules/_decimal/libmpdec/memory.h +--- Python-3.3.5/Modules/_decimal/libmpdec/memory.h 2014-03-09 09:40:25.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/memory.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,51 +0,0 @@ +-/* +- * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * +- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- */ +- +- +-#ifndef MEMORY_H +-#define MEMORY_H +- +- +-#include "mpdecimal.h" +- +- +-/* Internal header file: all symbols have local scope in the DSO */ +-MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) +- +- +-int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); +-int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); +-int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); +- +- +-MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ +- +- +-#endif +- +- +- +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/mpdecimal.c Python-3.3.5-android/Modules/_decimal/libmpdec/mpdecimal.c +--- Python-3.3.5/Modules/_decimal/libmpdec/mpdecimal.c 2014-03-09 09:40:25.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/mpdecimal.c 2014-08-05 16:12:06.000000000 +0200 +@@ -36,7 +36,7 @@ + #include "bits.h" + #include "convolute.h" + #include "crt.h" +-#include "memory.h" ++#include "mpmemory.h" + #include "typearith.h" + #include "umodarith.h" + +diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/mpmemory.h Python-3.3.5-android/Modules/_decimal/libmpdec/mpmemory.h +--- Python-3.3.5/Modules/_decimal/libmpdec/mpmemory.h 1970-01-01 01:00:00.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/mpmemory.h 2014-08-05 16:10:00.000000000 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++ ++#ifndef MEMORY_H ++#define MEMORY_H ++ ++ ++#include "mpdecimal.h" ++ ++ ++/* Internal header file: all symbols have local scope in the DSO */ ++MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) ++ ++ ++int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); ++int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); ++int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); ++ ++ ++MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ ++ ++ ++#endif ++ ++ ++ diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch new file mode 100644 index 0000000000..27ddcbbd3f --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch @@ -0,0 +1,255 @@ +diff -ru Python-3.3.5/Modules/Setup.dist Python-3.3.5-android/Modules/Setup.dist +--- Python-3.3.5/Modules/Setup.dist 2014-03-09 09:40:23.000000000 +0100 ++++ Python-3.3.5-android/Modules/Setup.dist 2014-08-04 22:16:29.000000000 +0200 +@@ -118,7 +118,7 @@ + itertools itertoolsmodule.c # Functions creating iterators for efficient looping + + # access to ISO C locale support +-_locale _localemodule.c # -lintl ++#_locale _localemodule.c # -lintl + + # Standard I/O baseline + _io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c +diff -ru Python-3.3.5/Modules/_decimal/libmpdec/io.c Python-3.3.5-android/Modules/_decimal/libmpdec/io.c +--- Python-3.3.5/Modules/_decimal/libmpdec/io.c 2014-03-09 09:40:25.000000000 +0100 ++++ Python-3.3.5-android/Modules/_decimal/libmpdec/io.c 2014-08-04 22:16:29.000000000 +0200 +@@ -868,10 +868,17 @@ + } + spec->type = *cp++; + spec->type = (spec->type == 'N') ? 'G' : 'g'; ++#ifdef __ANDROID__ ++ spec->dot = "."; ++ spec->sep = ","; ++ spec->grouping = "\3"; ++#else + lc = localeconv(); + spec->dot = lc->decimal_point; + spec->sep = lc->thousands_sep; + spec->grouping = lc->grouping; ++#endif ++ + if (mpd_validate_lconv(spec) < 0) { + return 0; /* GCOV_NOT_REACHED */ + } +diff -ru Python-3.3.5/Modules/_localemodule.c Python-3.3.5-android/Modules/_localemodule.c +--- Python-3.3.5/Modules/_localemodule.c 2014-03-09 09:40:26.000000000 +0100 ++++ Python-3.3.5-android/Modules/_localemodule.c 2014-08-04 22:16:29.000000000 +0200 +@@ -38,6 +38,13 @@ + #include + #endif + ++#if __ANDROID__ ++/* Android's locale support is pretty much unusable, it's better to have the ++ higher-level module fall back to C locale emulation. */ ++#error "Android's locale support is too incomplete to create a usable module." ++#endif ++ ++ + PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); + + static PyObject *Error; +@@ -141,6 +148,11 @@ + if (!result) + return NULL; + ++#ifdef __ANDROID__ ++ /* Don't even try on Android's broken locale.h. */ ++ goto failed; ++#else ++ + /* if LC_NUMERIC is different in the C library, use saved value */ + l = localeconv(); + +@@ -189,6 +201,7 @@ + RESULT_INT(p_sign_posn); + RESULT_INT(n_sign_posn); + return result; ++#endif // __ANDROID__ + + failed: + Py_XDECREF(result); +diff -ru Python-3.3.5/Modules/main.c Python-3.3.5-android/Modules/main.c +--- Python-3.3.5/Modules/main.c 2014-03-09 09:40:27.000000000 +0100 ++++ Python-3.3.5-android/Modules/main.c 2014-08-04 22:16:29.000000000 +0200 +@@ -522,7 +522,7 @@ + oldloc = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + /* Use utf-8 on Mac OS X */ + unicode = PyUnicode_FromString(p); + #else +diff -ru Python-3.3.5/Objects/unicodeobject.c Python-3.3.5-android/Objects/unicodeobject.c +--- Python-3.3.5/Objects/unicodeobject.c 2014-03-09 09:40:30.000000000 +0100 ++++ Python-3.3.5-android/Objects/unicodeobject.c 2014-08-04 22:16:29.000000000 +0200 +@@ -3295,13 +3295,22 @@ + static int + locale_error_handler(const char *errors, int *surrogateescape) + { ++ + if (errors == NULL) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + + if (strcmp(errors, "strict") == 0) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + if (strcmp(errors, "surrogateescape") == 0) { +@@ -3429,7 +3438,7 @@ + { + #ifdef HAVE_MBCS + return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -3709,7 +3718,7 @@ + { + #ifdef HAVE_MBCS + return PyUnicode_DecodeMBCS(s, size, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -4835,7 +4844,7 @@ + return NULL; + } + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + + /* Simplified UTF-8 decoder using surrogateescape error handler, + used to decode the command line arguments on Mac OS X. +diff -ru Python-3.3.5/Python/bltinmodule.c Python-3.3.5-android/Python/bltinmodule.c +--- Python-3.3.5/Python/bltinmodule.c 2014-03-09 09:40:32.000000000 +0100 ++++ Python-3.3.5-android/Python/bltinmodule.c 2014-08-04 22:16:29.000000000 +0200 +@@ -24,7 +24,7 @@ + #ifdef HAVE_MBCS + const char *Py_FileSystemDefaultEncoding = "mbcs"; + int Py_HasFileSystemDefaultEncoding = 1; +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + const char *Py_FileSystemDefaultEncoding = "utf-8"; + int Py_HasFileSystemDefaultEncoding = 1; + #else +diff -ru Python-3.3.5/Python/fileutils.c Python-3.3.5-android/Python/fileutils.c +--- Python-3.3.5/Python/fileutils.c 2014-03-09 09:40:32.000000000 +0100 ++++ Python-3.3.5-android/Python/fileutils.c 2014-08-04 22:16:29.000000000 +0200 +@@ -10,7 +10,7 @@ + #include + #endif + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); + #endif + +@@ -44,7 +44,7 @@ + Py_RETURN_NONE; + } + +-#if !defined(__APPLE__) && !defined(MS_WINDOWS) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) + extern int _Py_normalize_encoding(const char *, char *, size_t); + + /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. +@@ -194,7 +194,7 @@ + } + #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ + +-#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) + static wchar_t* + decode_ascii_surrogateescape(const char *arg, size_t *size) + { +@@ -241,7 +241,7 @@ + wchar_t* + _Py_char2wchar(const char* arg, size_t *size) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + wchar_t *wstr; + wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); + if (size != NULL) { +@@ -384,7 +384,7 @@ + char* + _Py_wchar2char(const wchar_t *text, size_t *error_pos) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + Py_ssize_t len; + PyObject *unicode, *bytes = NULL; + char *cpath; +diff -ru Python-3.3.5/Python/formatter_unicode.c Python-3.3.5-android/Python/formatter_unicode.c +--- Python-3.3.5/Python/formatter_unicode.c 2014-03-09 09:40:32.000000000 +0100 ++++ Python-3.3.5-android/Python/formatter_unicode.c 2014-08-04 22:16:29.000000000 +0200 +@@ -665,6 +665,7 @@ + { + switch (type) { + case LT_CURRENT_LOCALE: { ++#ifndef __ANDROID__ + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = PyUnicode_DecodeLocale( + locale_data->decimal_point, +@@ -680,6 +681,7 @@ + } + locale_info->grouping = locale_data->grouping; + break; ++#endif // __ANDROID__ + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); +diff -ru Python-3.3.5/Python/pystrtod.c Python-3.3.5-android/Python/pystrtod.c +--- Python-3.3.5/Python/pystrtod.c 2014-03-09 09:40:33.000000000 +0100 ++++ Python-3.3.5-android/Python/pystrtod.c 2014-08-04 22:16:29.000000000 +0200 +@@ -177,8 +177,12 @@ + + fail_pos = NULL; + ++#ifdef __ANDROID__ ++ decimal_point = "."; ++#else + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; ++#endif + decimal_point_len = strlen(decimal_point); + + assert(decimal_point_len != 0); +@@ -378,8 +382,12 @@ + Py_LOCAL_INLINE(void) + change_decimal_from_locale_to_dot(char* buffer) + { ++#ifdef __ANDROID__ ++ const char *decimal_point = "."; ++#else + struct lconv *locale_data = localeconv(); + const char *decimal_point = locale_data->decimal_point; ++#endif + + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + size_t decimal_point_len = strlen(decimal_point); +diff -ru Python-3.3.5/Python/pythonrun.c Python-3.3.5-android/Python/pythonrun.c +--- Python-3.3.5/Python/pythonrun.c 2014-03-09 09:40:33.000000000 +0100 ++++ Python-3.3.5-android/Python/pythonrun.c 2014-08-04 22:16:29.000000000 +0200 +@@ -188,6 +188,8 @@ + return NULL; + } + return get_codec_name(codeset); ++#elif __ANDROID__ ++ return get_codec_name("UTF-8"); + #else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch new file mode 100644 index 0000000000..4d8fc395c7 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch @@ -0,0 +1,313 @@ +diff -ru Python-3.3.5/Lib/platform.py Python-3.3.5-android/Lib/platform.py +--- Python-3.3.5/Lib/platform.py 2014-03-09 09:40:13.000000000 +0100 ++++ Python-3.3.5-android/Lib/platform.py 2014-08-04 22:19:36.000000000 +0200 +@@ -368,6 +368,63 @@ + supported_dists=supported_dists, + full_distribution_name=0) + ++_android_environment_vars = ( ++ 'ANDROID_PRIVATE', 'ANDROID_ARGUMENT', 'ANDROID_APP_PATH', 'ANDROID_DATA', ++ 'ANDROID_PROPERTY_WORKSPACE', 'ANDROID_BOOTLOGO') ++_android_version_property = 'ro.build.version.release' ++_android_buildstr_property = 'ro.build.version.full' ++ ++def android_version(version='', buildstr=''): ++ """ Attempt to get the Android version number and build string. ++ ++ The function checks for the getprop binary to retrieve build info, ++ and falls back to manually reading /system/build.prop if available. ++ ++ Returns a (version, buildstr) tuple which defaults to the args given ++ as parameters. ++ """ ++ if not any(os.getenv(e) for e in _android_environment_vars): ++ # Probably not on Android... ++ return version, buildstr ++ ++ version_obtained = False ++ buildstr_obtained = False ++ ++ # Try the 'official' API tool first, since /system/build.prop might ++ # not be the only source for properties. ++ if os.access('/system/bin/getprop', os.X_OK): ++ try: ++ output = subprocess.check_output(['/system/bin/getprop', ++ _android_version_property]) ++ version = output.decode('ascii').strip() ++ version_obtained = True ++ except (subprocess.CalledProcessError, UnicodeDecodeError): ++ pass ++ ++ try: ++ output = subprocess.check_output(['/system/bin/getprop', ++ _android_buildstr_property]) ++ buildstr = output.decode('ascii').strip() ++ buildstr_obtained = True ++ except (subprocess.CalledProcessError, UnicodeDecodeError): ++ pass ++ done = version_obtained and buildstr_obtained ++ ++ # Fall back to parsing /system/build.prop manually. ++ if not done and os.path.isfile('/system/build.prop'): ++ for line in open('/system/build.prop'): ++ if '=' not in line: ++ continue ++ key, val = line.split('=') ++ key = key.strip() ++ ++ if not version_obtained and key == _android_version_property: ++ version = val.strip() ++ elif not buildstr_obtained and key == _android_buildstr_property: ++ buildstr = val.strip() ++ ++ return version, buildstr ++ + def popen(cmd, mode='r', bufsize=-1): + + """ Portable popen() interface. +diff -ru Python-3.3.5/Lib/subprocess.py Python-3.3.5-android/Lib/subprocess.py +--- Python-3.3.5/Lib/subprocess.py 2014-03-09 09:40:13.000000000 +0100 ++++ Python-3.3.5-android/Lib/subprocess.py 2014-08-04 22:19:36.000000000 +0200 +@@ -1343,9 +1343,18 @@ + args = list(args) + + if shell: +- args = ["/bin/sh", "-c"] + args + if executable: +- args[0] = executable ++ main = executable ++ elif os.path.isfile('/bin/sh'): ++ main = '/bin/sh' ++ else: ++ import platform ++ if platform.android_version()[0]: ++ main = '/system/bin/sh' ++ else: ++ raise RuntimeError('Could not find system shell') ++ ++ args = [main, "-c"] + args + + if executable is None: + executable = args[0] +diff -ru Python-3.3.5/Lib/test/test_subprocess.py Python-3.3.5-android/Lib/test/test_subprocess.py +--- Python-3.3.5/Lib/test/test_subprocess.py 2014-03-09 09:40:19.000000000 +0100 ++++ Python-3.3.5-android/Lib/test/test_subprocess.py 2014-08-04 22:19:36.000000000 +0200 +@@ -17,6 +17,7 @@ + import shutil + import gc + import textwrap ++import platform + + try: + import resource +@@ -1356,7 +1357,10 @@ + fd, fname = mkstemp() + # reopen in text mode + with open(fd, "w", errors="surrogateescape") as fobj: +- fobj.write("#!/bin/sh\n") ++ if platform.android_version()[0]: ++ fobj.write('#!/system/bin/sh\n') ++ else: ++ fobj.write("#!/bin/sh\n") + fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % + sys.executable) + os.chmod(fname, 0o700) +@@ -1401,7 +1405,10 @@ + fd, fname = mkstemp() + # reopen in text mode + with open(fd, "w", errors="surrogateescape") as fobj: +- fobj.write("#!/bin/sh\n") ++ if platform.android_version()[0]: ++ fobj.write('#!/system/bin/sh\n') ++ else: ++ fobj.write("#!/bin/sh\n") + fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % + sys.executable) + os.chmod(fname, 0o700) +diff -ru Python-3.4.2/Modules/pwdmodule.c Python-3.4.2-android/Modules/pwdmodule.c +--- Python-3.4.2/Modules/pwdmodule.c 2015-02-24 23:06:31.000000000 +0100 ++++ Python-3.4.2-android/Modules/pwdmodule.c 2015-02-24 23:09:14.000000000 +0100 +@@ -72,7 +72,11 @@ + SETS(setIndex++, p->pw_passwd); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); ++#if !defined(__ANDROID__) + SETS(setIndex++, p->pw_gecos); ++#else ++ SETS(setIndex++, ""); ++#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + +diff -ru Python-3.3.5/Modules/socketmodule.c Python-3.3.5-android/Modules/socketmodule.c +--- Python-3.3.5/Modules/socketmodule.c 2014-03-09 09:40:28.000000000 +0100 ++++ Python-3.3.5-android/Modules/socketmodule.c 2014-08-04 22:19:36.000000000 +0200 +@@ -150,7 +150,7 @@ + On the other hand, not all Linux versions agree, so there the settings + computed by the configure script are needed! */ + +-#ifndef linux ++#if !defined(linux) || __ANDROID__ + # undef HAVE_GETHOSTBYNAME_R_3_ARG + # undef HAVE_GETHOSTBYNAME_R_5_ARG + # undef HAVE_GETHOSTBYNAME_R_6_ARG +@@ -169,7 +169,7 @@ + # define HAVE_GETHOSTBYNAME_R_3_ARG + # elif defined(__sun) || defined(__sgi) + # define HAVE_GETHOSTBYNAME_R_5_ARG +-# elif defined(linux) ++# elif defined(linux) && !__ANDROID__ + /* Rely on the configure script */ + # else + # undef HAVE_GETHOSTBYNAME_R +diff -ru Python-3.3.5/Modules/posixmodule.c Python-3.3.5-android/Modules/posixmodule.c +--- Python-3.3.5/Modules/posixmodule.c 2014-03-09 08:40:28.000000000 +0000 ++++ Python-3.3.5-android/Modules/posixmodule.c 2015-02-24 19:57:05.368843433 +0000 +@@ -403,6 +403,11 @@ + #endif + #endif + ++/* Android doesn't expose AT_EACCESS - manually define it. */ ++#if !defined(AT_EACCESS) && defined(__ANDROID__) ++#define AT_EACCESS 0x200 ++#endif ++ + + #ifdef MS_WINDOWS + static int +diff -ru Python-3.3.5/Python/pytime.c Python-3.3.5-android/Python/pytime.c +--- Python-3.3.5/Python/pytime.c 2015-02-23 11:54:25.000000000 -0500 ++++ Python-3.3.5-android/Python/pytime.c 2015-02-23 11:55:19.000000000 -0500 +@@ -3,7 +3,7 @@ + #include + #endif + +-#if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) ++#if (defined(__APPLE__) || defined(__ANDROID__)) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) + /* + * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter + * might fail on some platforms. This fallback is unwanted on MacOSX because +diff -ru Python-3.4.2/configure Python-3.4.2-android/configure +--- Python-3.4.2/configure 2015-02-24 23:18:31.000000000 +0100 ++++ Python-3.4.2-android/configure 2015-03-01 20:15:02.000000000 +0100 +@@ -5406,6 +5406,34 @@ + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + + ++# Test if we're running on Android. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 ++$as_echo_n "checking if target is Android-based... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++#if __ANDROID__ ++yes ++#endif ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "yes" >/dev/null 2>&1; then : ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ with_android=yes ++ ++else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ with_android=no ++ ++ ++fi ++rm -f conftest* ++ + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5 +@@ -5650,7 +5678,14 @@ + SOVERSION=`echo $SOVERSION|cut -d "." -f 1` + ;; + esac +- INSTSONAME="$LDLIBRARY".$SOVERSION ++ ++ if test "$with_android" != yes ++ then ++ INSTSONAME="$LDLIBRARY".$SOVERSION ++ else ++ INSTSONAME="$LDLIBRARY" ++ fi ++ + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so +diff -ru Python-3.4.2/configure.ac Python-3.4.2-android/configure.ac +--- Python-3.4.2/configure.ac 2015-02-24 23:18:31.000000000 +0100 ++++ Python-3.4.2-android/configure.ac 2015-03-01 20:14:54.000000000 +0100 +@@ -796,6 +796,21 @@ + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + AC_SUBST(MULTIARCH) + ++# Test if we're running on Android. ++AC_MSG_CHECKING(if target is Android-based) ++AC_EGREP_CPP(yes, ++[ ++#if __ANDROID__ ++yes ++#endif ++], [ ++ AC_MSG_RESULT(yes) ++ with_android=yes ++ ], [ ++ AC_MSG_RESULT(no) ++ with_android=no ++ ] ++) + + AC_SUBST(LIBRARY) + AC_MSG_CHECKING(LIBRARY) +@@ -970,7 +985,14 @@ + SOVERSION=`echo $SOVERSION|cut -d "." -f 1` + ;; + esac +- INSTSONAME="$LDLIBRARY".$SOVERSION ++ ++ if test "$with_android" != yes ++ then ++ INSTSONAME="$LDLIBRARY".$SOVERSION ++ else ++ INSTSONAME="$LDLIBRARY" ++ fi ++ + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so + +diff -ru Python-3.4.2/Makefile.pre.in Python-3.4.2-android/Makefile.pre.in +--- Python-3.4.2/Makefile.pre.in 2015-03-04 16:25:36.000000000 +0100 ++++ Python-3.4.2-android/Makefile.pre.in 2015-03-04 16:27:27.000000000 +0100 +@@ -568,7 +568,7 @@ + *\ -s*|s*) quiet="-q";; \ + *) quiet="";; \ + esac; \ +- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ ++ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED) -lpython$(LDVERSION)' OPT='$(OPT)' \ + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ + $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build + +diff -Nru Python-3.4.2/Makefile.pre.in Python-3.4.2-android/Makefile.pre.in +--- Python-3.4.2/Makefile.pre.in 2015-06-27 17:04:23.885777456 +0000 ++++ Python-3.4.2-android/Makefile.pre.in 2015-06-27 17:05:27.709777315 +0000 +@@ -585,11 +585,9 @@ + $(RANLIB) $@ + + libpython$(LDVERSION).so: $(LIBRARY_OBJS) ++ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + if test $(INSTSONAME) != $(LDLIBRARY); then \ +- $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + $(LN) -f $(INSTSONAME) $@; \ +- else \ +- $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + fi + + libpython3.so: libpython$(LDVERSION).so diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch new file mode 100644 index 0000000000..2bfcf6925d --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch @@ -0,0 +1,17 @@ +diff -ru Python-3.3.5/Modules/_posixsubprocess.c Python-3.3.5-android/Modules/_posixsubprocess.c +--- Python-3.3.5/Modules/_posixsubprocess.c 2014-03-09 09:40:26.000000000 +0100 ++++ Python-3.3.5-android/Modules/_posixsubprocess.c 2014-08-04 22:19:36.000000000 +0200 +@@ -18,6 +18,12 @@ + #include + #endif + ++#if defined(__ANDROID__) ++/* Android doesn't expose syscalls. Let's add the definition manually. */ ++# include ++# define SYS_getdents64 __NR_getdents64 ++#endif ++ + #if defined(sun) + /* readdir64 is used to work around Solaris 9 bug 6395699. */ + # define readdir readdir64 + diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch new file mode 100644 index 0000000000..7bceb49180 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch @@ -0,0 +1,78 @@ +diff -ru Python-3.3.5/Makefile.pre.in Python-3.3.5-android/Makefile.pre.in +--- Python-3.3.5/Makefile.pre.in 2014-03-09 09:40:23.000000000 +0100 ++++ Python-3.3.5-android/Makefile.pre.in 2014-08-04 22:13:00.000000000 +0200 +@@ -674,7 +674,7 @@ + $(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS) + @$(MKDIR_P) Include + $(MAKE) $(PGEN) +- $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) ++ $(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) + $(GRAMMAR_C): $(GRAMMAR_H) $(GRAMMAR_INPUT) $(PGENSRCS) + $(MAKE) $(GRAMMAR_H) + touch $(GRAMMAR_C) +@@ -1243,6 +1243,7 @@ + # Install the dynamically loadable modules + # This goes into $(exec_prefix) + sharedinstall: sharedmods ++ CC='$(CC)' LDSHARED='$(BLDSHARED)' LDFLAGS='$(LDFLAGS)' OPT='$(OPT)' CROSS_COMPILE='$(CROSS_COMPILE)' \ + $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ + --prefix=$(prefix) \ + --install-scripts=$(BINDIR) \ +diff -ru Python-3.3.5/configure Python-3.3.5-android/configure +--- Python-3.3.5/configure 2014-03-09 09:40:34.000000000 +0100 ++++ Python-3.3.5-android/configure 2014-08-04 22:13:00.000000000 +0200 +@@ -2943,13 +2943,18 @@ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python interpreter for cross build" >&5 + $as_echo_n "checking for python interpreter for cross build... " >&6; } + if test -z "$PYTHON_FOR_BUILD"; then +- for interp in python$PACKAGE_VERSION python3 python; do +- which $interp >/dev/null 2>&1 || continue +- if $interp -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then +- break +- fi +- interp= +- done ++ if test ! -z "$HOSTPYTHON" && PYTHONPATH="$ac_abs_confdir/Lib" "$HOSTPYTHON" -S -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then ++ interp="$HOSTPYTHON" ++ else ++ for interp in python$PACKAGE_VERSION python3 python; do ++ which $interp >/dev/null 2>&1 || continue ++ if $interp -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then ++ break ++ fi ++ interp= ++ done ++ fi ++ + if test x$interp = x; then + as_fn_error $? "python$PACKAGE_VERSION interpreter not found" "$LINENO" 5 + fi +diff -ru Python-3.3.5/configure.ac Python-3.3.5-android/configure.ac +--- Python-3.3.5/configure.ac 2014-03-09 09:40:34.000000000 +0100 ++++ Python-3.3.5-android/configure.ac 2014-08-04 22:13:00.000000000 +0200 +@@ -56,13 +56,18 @@ + if test "$cross_compiling" = yes; then + AC_MSG_CHECKING([for python interpreter for cross build]) + if test -z "$PYTHON_FOR_BUILD"; then +- for interp in python$PACKAGE_VERSION python3 python; do +- which $interp >/dev/null 2>&1 || continue +- if $interp -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then +- break +- fi +- interp= +- done ++ if test ! -z "$HOSTPYTHON" && PYTHONPATH="$ac_abs_confdir/Lib" "$HOSTPYTHON" -S -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then ++ interp="$HOSTPYTHON" ++ else ++ for interp in python$PACKAGE_VERSION python3 python; do ++ which $interp >/dev/null 2>&1 || continue ++ if $interp -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then ++ break ++ fi ++ interp= ++ done ++ fi ++ + if test x$interp = x; then + AC_MSG_ERROR([python$PACKAGE_VERSION interpreter not found]) + fi diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch new file mode 100644 index 0000000000..be2bde20d2 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch @@ -0,0 +1,42 @@ +diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c +index 7f8f134..bba560f 100644 +--- a/Python/dynload_shlib.c ++++ b/Python/dynload_shlib.c +@@ -62,6 +62,20 @@ _PyImport_FindSharedFuncptr(const char *prefix, + char pathbuf[260]; + int dlopenflags=0; + ++ static void *libpymodules = NULL; ++ void *rv = NULL; ++ ++ /* Ensure we have access to libpymodules. */ ++ if (libpymodules == NULL) { ++ printf("ANDROID_PRIVATE = %s\n", getenv("ANDROID_PRIVATE")); ++ PyOS_snprintf(pathbuf, sizeof(pathbuf), "%s/libpymodules.so", getenv("ANDROID_PRIVATE")); ++ libpymodules = dlopen(pathbuf, RTLD_NOW); ++ ++ if (libpymodules == NULL) { ++ //abort(); ++ } ++ } ++ + if (strchr(pathname, '/') == NULL) { + /* Prefix bare filename with "./" */ + PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); +@@ -71,6 +85,16 @@ _PyImport_FindSharedFuncptr(const char *prefix, + PyOS_snprintf(funcname, sizeof(funcname), + LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); + ++ ++ /* Read symbols that have been linked into the main binary. */ ++ ++ if (libpymodules) { ++ rv = dlsym(libpymodules, funcname); ++ if (rv != NULL) { ++ return rv; ++ } ++ } ++ + if (fp != NULL) { + int i; + struct _Py_stat_struct status; diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch new file mode 100644 index 0000000000..5745062551 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch @@ -0,0 +1,86 @@ +diff -ru Python-3.3.5/Lib/test/test_pwd.py Python-3.3.5-android/Lib/test/test_pwd.py +--- Python-3.3.5/Lib/test/test_pwd.py 2014-03-09 09:40:19.000000000 +0100 ++++ Python-3.3.5-android/Lib/test/test_pwd.py 2014-08-04 22:14:36.000000000 +0200 +@@ -6,6 +6,7 @@ + + class PwdTest(unittest.TestCase): + ++ @unittest.skipUnless(hasattr(pwd, 'getpwall'), 'pwd module does not expose getpwall()') + def test_values(self): + entries = pwd.getpwall() + +@@ -52,6 +53,7 @@ + self.assertIn(pwd.getpwnam(e.pw_name), entriesbyname[e.pw_name]) + self.assertIn(pwd.getpwuid(e.pw_uid), entriesbyuid[e.pw_uid]) + ++ @unittest.skipUnless(hasattr(pwd, 'getpwall'), 'pwd module does not expose getpwall()') + def test_errors(self): + self.assertRaises(TypeError, pwd.getpwuid) + self.assertRaises(TypeError, pwd.getpwuid, 3.14) +diff -ru Python-3.4.2/Modules/python.c Python-3.4.2-android/Modules/python.c +--- Python-3.4.2/Modules/python.c 2015-02-24 22:42:37.000000000 +0100 ++++ Python-3.4.2-android/Modules/python.c 2015-02-24 23:04:27.000000000 +0100 +@@ -44,10 +44,13 @@ + fpsetmask(m & ~FP_X_OFL); + #endif + +- oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); +- if (!oldloc) { +- fprintf(stderr, "out of memory\n"); +- return 1; ++ oldloc = setlocale(LC_ALL, NULL); ++ if (oldloc) { ++ oldloc = _PyMem_RawStrdup(oldloc); ++ if (!oldloc) { ++ fprintf(stderr, "out of memory\n"); ++ return 1; ++ } + } + + setlocale(LC_ALL, ""); +@@ -64,8 +67,11 @@ + } + argv_copy2[argc] = argv_copy[argc] = NULL; + +- setlocale(LC_ALL, oldloc); +- PyMem_RawFree(oldloc); ++ if (oldloc) { ++ setlocale(LC_ALL, oldloc); ++ PyMem_RawFree(oldloc); ++ } ++ + res = Py_Main(argc, argv_copy); + for (i = 0; i < argc; i++) { + PyMem_RawFree(argv_copy2[i]); +diff -ru Python-3.3.5/setup.py Python-3.3.5-android/setup.py +--- Python-3.3.5/setup.py 2014-03-09 09:40:35.000000000 +0100 ++++ Python-3.3.5-android/setup.py 2014-08-04 22:14:36.000000000 +0200 +@@ -562,7 +562,7 @@ + libraries=math_libs) ) + + # time libraries: librt may be needed for clock_gettime() +- time_libs = [] ++ time_libs = ['m'] + lib = sysconfig.get_config_var('TIMEMODULE_LIB') + if lib: + time_libs.append(lib) +@@ -639,7 +639,8 @@ + # Operations on audio samples + # According to #993173, this one should actually work fine on + # 64-bit platforms. +- exts.append( Extension('audioop', ['audioop.c']) ) ++ exts.append( Extension('audioop', ['audioop.c'], ++ libraries=['m']) ) + + # readline + do_readline = self.compiler.find_library_file(lib_dirs, 'readline') +@@ -1904,7 +1905,8 @@ + sources=sources, + depends=depends) + ext_test = Extension('_ctypes_test', +- sources=['_ctypes/_ctypes_test.c']) ++ sources=['_ctypes/_ctypes_test.c'], ++ libraries=['m']) + self.extensions.extend([ext, ext_test]) + + if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"): diff --git a/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch b/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch new file mode 100644 index 0000000000..d51684e5d6 --- /dev/null +++ b/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch @@ -0,0 +1,573 @@ +diff --git a/Lib/platform.py b/Lib/platform.py +index 9096696..66a6455 100755 +--- a/Lib/platform.py ++++ b/Lib/platform.py +@@ -382,6 +382,64 @@ def dist(distname='', version='', id='', + supported_dists=supported_dists, + full_distribution_name=0) + ++_android_environment_vars = ( ++ 'ANDROID_ROOT', 'ANDROID_ASSETS', 'ANDROID_STORAGE', 'ANDROID_DATA', ++ 'ANDROID_PROPERTY_WORKSPACE', 'ANDROID_BOOTLOGO') ++_android_version_property = 'ro.build.version.release' ++_android_buildstr_property = 'ro.build.version.full' ++ ++def android_version(version='', buildstr=''): ++ """ Attempt to get the Android version number and build string. ++ ++ The function checks for the getprop binary to retrieve build info, ++ and falls back to manually reading /system/build.prop if available. ++ ++ Returns a (version, buildstr) tuple which defaults to the args given ++ as parameters. ++ """ ++ if not any(os.getenv(e) for e in _android_environment_vars): ++ # Probably not on Android... ++ return version, buildstr ++ ++ version_obtained = False ++ buildstr_obtained = False ++ ++ # Try the 'official' API tool first, since /system/build.prop might ++ # not be the only source for properties. ++ if os.access('/system/bin/getprop', os.X_OK): ++ try: ++ output = subprocess.check_output(['/system/bin/getprop', ++ _android_version_property]) ++ version = output.decode('ascii').strip() ++ version_obtained = True ++ except (subprocess.CalledProcessError, UnicodeDecodeError): ++ pass ++ ++ try: ++ output = subprocess.check_output(['/system/bin/getprop', ++ _android_buildstr_property]) ++ buildstr = output.decode('ascii').strip() ++ buildstr_obtained = True ++ except (subprocess.CalledProcessError, UnicodeDecodeError): ++ pass ++ done = version_obtained and buildstr_obtained ++ ++ # Fall back to parsing /system/build.prop manually. ++ if not done and os.path.isfile('/system/build.prop'): ++ for line in open('/system/build.prop'): ++ if '=' not in line: ++ continue ++ key, val = line.split('=') ++ key = key.strip() ++ ++ if not version_obtained and key == _android_version_property: ++ version = val.strip() ++ elif not buildstr_obtained and key == _android_buildstr_property: ++ buildstr = val.strip() ++ ++ return version, buildstr ++ ++ + def popen(cmd, mode='r', bufsize=-1): + + """ Portable popen() interface. +diff --git a/Lib/subprocess.py b/Lib/subprocess.py +index b6c4374..51dec9c 100644 +--- a/Lib/subprocess.py ++++ b/Lib/subprocess.py +@@ -1429,9 +1429,18 @@ class Popen(object): + args = list(args) + + if shell: +- args = ["/bin/sh", "-c"] + args + if executable: +- args[0] = executable ++ main = executable ++ elif os.path.isfile('/bin/sh'): ++ main = '/bin/sh' ++ else: ++ import platform ++ if platform.android_version()[0]: ++ main = '/system/bin/sh' ++ else: ++ raise RuntimeError('Could not find system shell') ++ ++ args = [main, "-c"] + args + + if executable is None: + executable = args[0] +diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py +index 9c0229a..d711647 100644 +--- a/Lib/test/test_subprocess.py ++++ b/Lib/test/test_subprocess.py +@@ -18,6 +18,7 @@ import select + import shutil + import gc + import textwrap ++import platform + + try: + import threading +@@ -1530,8 +1531,11 @@ class POSIXProcessTestCase(BaseTestCase): + fd, fname = mkstemp() + # reopen in text mode + with open(fd, "w", errors="surrogateescape") as fobj: +- fobj.write("#!/bin/sh\n") +- fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % ++ if platform.android_version()[0]: ++ fobj.write('#!/system/bin/sh\n') ++ else: ++ fobj.write("#!/bin/sh\n") ++ fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % + sys.executable) + os.chmod(fname, 0o700) + p = subprocess.Popen(fname) +@@ -1575,7 +1579,10 @@ class POSIXProcessTestCase(BaseTestCase): + fd, fname = mkstemp() + # reopen in text mode + with open(fd, "w", errors="surrogateescape") as fobj: +- fobj.write("#!/bin/sh\n") ++ if platform.android_version()[0]: ++ fobj.write('#!/system/bin/sh\n') ++ else: ++ fobj.write("#!/bin/sh\n") + fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % + sys.executable) + os.chmod(fname, 0o700) +diff --git a/Makefile.pre.in b/Makefile.pre.in +index ce2c0aa..cc401eb 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -580,7 +580,7 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt + *\ -s*|s*) quiet="-q";; \ + *) quiet="";; \ + esac; \ +- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ ++ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED) -lpython$(LDVERSION)' OPT='$(OPT)' \ + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ + $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build + +@@ -597,11 +597,9 @@ $(LIBRARY): $(LIBRARY_OBJS) + $(RANLIB) $@ + + libpython$(LDVERSION).so: $(LIBRARY_OBJS) ++ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + if test $(INSTSONAME) != $(LDLIBRARY); then \ +- $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + $(LN) -f $(INSTSONAME) $@; \ +- else \ +- $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + fi + + libpython3.so: libpython$(LDVERSION).so +diff --git a/Modules/Setup.dist b/Modules/Setup.dist +index 06ba6ad..3c5115c 100644 +--- a/Modules/Setup.dist ++++ b/Modules/Setup.dist +@@ -121,7 +121,7 @@ _stat _stat.c # stat.h interface + time timemodule.c # -lm # time operations and variables + + # access to ISO C locale support +-_locale _localemodule.c # -lintl ++#_locale _localemodule.c # -lintl + + # Standard I/O baseline + _io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c +diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c +index a45a429..e87101d 100644 +--- a/Modules/_decimal/libmpdec/io.c ++++ b/Modules/_decimal/libmpdec/io.c +@@ -868,10 +868,16 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) + } + spec->type = *cp++; + spec->type = (spec->type == 'N') ? 'G' : 'g'; ++#ifdef __ANDROID__ ++ spec->dot = "."; ++ spec->sep = ","; ++ spec->grouping = "\3"; ++#else + lc = localeconv(); + spec->dot = lc->decimal_point; + spec->sep = lc->thousands_sep; + spec->grouping = lc->grouping; ++#endif + if (mpd_validate_lconv(spec) < 0) { + return 0; /* GCOV_NOT_REACHED */ + } +diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c +index b1d6add..2c6ec0e 100644 +--- a/Modules/_localemodule.c ++++ b/Modules/_localemodule.c +@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. + #include + #endif + ++#if __ANDROID__ ++/* Android's locale support is pretty much unusable, it's better to have the ++ higher-level module fall back to C locale emulation. */ ++#error "Android's locale support is too incomplete to create a usable module." ++#endif ++ ++ + PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); + + static PyObject *Error; +@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) + if (!result) + return NULL; + ++#ifdef __ANDROID__ ++ /* Don't even try on Android's broken locale.h. */ ++ goto failed; ++#else ++ + /* if LC_NUMERIC is different in the C library, use saved value */ + l = localeconv(); + +@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) + RESULT_INT(n_sign_posn); + return result; + ++#endif // __ANDROID__ ++ + failed: + Py_XDECREF(result); + return NULL; +diff --git a/Modules/main.c b/Modules/main.c +index 2a9ea28..e32f305 100644 +--- a/Modules/main.c ++++ b/Modules/main.c +@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + /* Use utf-8 on Mac OS X */ + unicode = PyUnicode_FromString(p); + #else +diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c +index ec8c526..08e8021 100644 +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); + PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, + ULONG, struct _Py_stat_struct *); + #endif ++ ++/* Android doesn't expose AT_EACCESS - manually define it. */ ++#if !defined(AT_EACCESS) && defined(__ANDROID__) ++#define AT_EACCESS 0x200 ++#endif + + #ifdef MS_WINDOWS + static int +diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c +index 281c30b..28b93c2 100644 +--- a/Modules/pwdmodule.c ++++ b/Modules/pwdmodule.c +@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) + SETS(setIndex++, p->pw_passwd); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); ++#if !defined(__ANDROID__) + SETS(setIndex++, p->pw_gecos); ++#else ++ SETS(setIndex++, ""); ++#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + +diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c +index ee24907..3718f70 100644 +--- a/Modules/socketmodule.c ++++ b/Modules/socketmodule.c +@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + On the other hand, not all Linux versions agree, so there the settings + computed by the configure script are needed! */ + +-#ifndef linux ++#if !defined(linux) || __ANDROID__ + # undef HAVE_GETHOSTBYNAME_R_3_ARG + # undef HAVE_GETHOSTBYNAME_R_5_ARG + # undef HAVE_GETHOSTBYNAME_R_6_ARG +@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + # define HAVE_GETHOSTBYNAME_R_3_ARG + # elif defined(__sun) || defined(__sgi) + # define HAVE_GETHOSTBYNAME_R_5_ARG +-# elif defined(linux) ++# elif defined(linux) && !__ANDROID__ + /* Rely on the configure script */ + # else + # undef HAVE_GETHOSTBYNAME_R +diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c +index 9223c99..1f8f625 100644 +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -3163,12 +3163,20 @@ static int + locale_error_handler(const char *errors, int *surrogateescape) + { + if (errors == NULL) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + + if (strcmp(errors, "strict") == 0) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + if (strcmp(errors, "surrogateescape") == 0) { +@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) + { + #ifdef HAVE_MBCS + return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) + { + #ifdef HAVE_MBCS + return PyUnicode_DecodeMBCS(s, size, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -4769,7 +4777,7 @@ onError: + return NULL; + } + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + + /* Simplified UTF-8 decoder using surrogateescape error handler, + used to decode the command line arguments on Mac OS X. +diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c +index 2f22209..ba42d84 100644 +--- a/Python/bltinmodule.c ++++ b/Python/bltinmodule.c +@@ -24,7 +24,7 @@ + #ifdef HAVE_MBCS + const char *Py_FileSystemDefaultEncoding = "mbcs"; + int Py_HasFileSystemDefaultEncoding = 1; +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + const char *Py_FileSystemDefaultEncoding = "utf-8"; + int Py_HasFileSystemDefaultEncoding = 1; + #else +diff --git a/Python/fileutils.c b/Python/fileutils.c +index bccd321..48ae1a5 100644 +--- a/Python/fileutils.c ++++ b/Python/fileutils.c +@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); + #include + #endif /* HAVE_FCNTL_H */ + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); + #endif + +@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) + Py_RETURN_NONE; + } + +-#if !defined(__APPLE__) && !defined(MS_WINDOWS) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) + extern int _Py_normalize_encoding(const char *, char *, size_t); + + /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. +@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) + } + #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ + +-#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) + static wchar_t* + decode_ascii_surrogateescape(const char *arg, size_t *size) + { +@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) + wchar_t* + Py_DecodeLocale(const char* arg, size_t *size) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + wchar_t *wstr; + wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); + if (size != NULL) { +@@ -423,7 +423,7 @@ oom: + char* + Py_EncodeLocale(const wchar_t *text, size_t *error_pos) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + Py_ssize_t len; + PyObject *unicode, *bytes = NULL; + char *cpath; +diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c +index 056bb76..c9d761e 100644 +--- a/Python/formatter_unicode.c ++++ b/Python/formatter_unicode.c +@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + { + switch (type) { + case LT_CURRENT_LOCALE: { ++#ifndef __ANDROID__ + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = PyUnicode_DecodeLocale( + locale_data->decimal_point, +@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + } + locale_info->grouping = locale_data->grouping; + break; ++#endif // __ANDROID__ + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); +diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c +index a17adf7..0843158 100644 +--- a/Python/pylifecycle.c ++++ b/Python/pylifecycle.c +@@ -224,6 +224,8 @@ get_locale_encoding(void) + return NULL; + } + return get_codec_name(codeset); ++#elif __ANDROID__ ++ return get_codec_name("UTF-8"); + #else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +diff --git a/Python/pystrtod.c b/Python/pystrtod.c +index 209c908..6bd792a 100644 +--- a/Python/pystrtod.c ++++ b/Python/pystrtod.c +@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) + + fail_pos = NULL; + ++#ifdef __ANDROID__ ++ decimal_point = "."; ++#else + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; ++#endif + decimal_point_len = strlen(decimal_point); + + assert(decimal_point_len != 0); +@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, + Py_LOCAL_INLINE(void) + change_decimal_from_locale_to_dot(char* buffer) + { ++#ifdef __ANDROID__ ++ const char *decimal_point = "."; ++#else + struct lconv *locale_data = localeconv(); + const char *decimal_point = locale_data->decimal_point; ++#endif + + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + size_t decimal_point_len = strlen(decimal_point); +diff --git a/configure b/configure +index e823a08..dc7c760 100755 +--- a/configure ++++ b/configure +@@ -5065,6 +5065,35 @@ fi + + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + ++# Test if we're running on Android. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 ++$as_echo_n "checking if target is Android-based... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++#if __ANDROID__ ++yes ++#endif ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "yes" >/dev/null 2>&1; then : ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ with_android=yes ++ ++else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ with_android=no ++ ++ ++fi ++rm -f conftest* ++ ++ + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 + $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } +@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +- INSTSONAME="$LDLIBRARY".$SOVERSION ++ if test "$with_android" != yes ++ then ++ INSTSONAME="$LDLIBRARY".$SOVERSION ++ else ++ INSTSONAME="LDLIBRARY" ++ fi ++ + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so +diff --git a/configure.ac b/configure.ac +index 56a73df..3245d87 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -726,6 +726,22 @@ fi + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + AC_SUBST(MULTIARCH) + ++# Test if we're running on Android. ++AC_MSG_CHECKING(if target is Android-based) ++AC_EGREP_CPP(yes, ++[ ++#if __ANDROID__ ++yes ++#endif ++], [ ++ AC_MSG_RESULT(yes) ++ with_android=yes ++ ], [ ++ AC_MSG_RESULT(no) ++ with_android=no ++ ] ++) ++ + AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) + cat >> conftest.c <type = *cp++; + spec->type = (spec->type == 'N') ? 'G' : 'g'; ++#ifdef __ANDROID__ ++ spec->dot = "."; ++ spec->sep = ","; ++ spec->grouping = "\3"; ++#else + lc = localeconv(); + spec->dot = lc->decimal_point; + spec->sep = lc->thousands_sep; + spec->grouping = lc->grouping; ++#endif + if (mpd_validate_lconv(spec) < 0) { + return 0; /* GCOV_NOT_REACHED */ + } +diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c +index b1d6add..2c6ec0e 100644 +--- a/Modules/_localemodule.c ++++ b/Modules/_localemodule.c +@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. + #include + #endif + ++#if __ANDROID__ ++/* Android's locale support is pretty much unusable, it's better to have the ++ higher-level module fall back to C locale emulation. */ ++#error "Android's locale support is too incomplete to create a usable module." ++#endif ++ ++ + PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); + + static PyObject *Error; +@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) + if (!result) + return NULL; + ++#ifdef __ANDROID__ ++ /* Don't even try on Android's broken locale.h. */ ++ goto failed; ++#else ++ + /* if LC_NUMERIC is different in the C library, use saved value */ + l = localeconv(); + +@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) + RESULT_INT(n_sign_posn); + return result; + ++#endif // __ANDROID__ ++ + failed: + Py_XDECREF(result); + return NULL; +diff --git a/Modules/main.c b/Modules/main.c +index 2a9ea28..e32f305 100644 +--- a/Modules/main.c ++++ b/Modules/main.c +@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + /* Use utf-8 on Mac OS X */ + unicode = PyUnicode_FromString(p); + #else +diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c +index ec8c526..08e8021 100644 +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); + PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, + ULONG, struct _Py_stat_struct *); + #endif ++ ++/* Android doesn't expose AT_EACCESS - manually define it. */ ++#if !defined(AT_EACCESS) && defined(__ANDROID__) ++#define AT_EACCESS 0x200 ++#endif + + #ifdef MS_WINDOWS + static int +diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c +index 281c30b..28b93c2 100644 +--- a/Modules/pwdmodule.c ++++ b/Modules/pwdmodule.c +@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) + SETS(setIndex++, p->pw_passwd); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); ++#if !defined(__ANDROID__) + SETS(setIndex++, p->pw_gecos); ++#else ++ SETS(setIndex++, ""); ++#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + +diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c +index ee24907..3718f70 100644 +--- a/Modules/socketmodule.c ++++ b/Modules/socketmodule.c +@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + On the other hand, not all Linux versions agree, so there the settings + computed by the configure script are needed! */ + +-#ifndef linux ++#if !defined(linux) || __ANDROID__ + # undef HAVE_GETHOSTBYNAME_R_3_ARG + # undef HAVE_GETHOSTBYNAME_R_5_ARG + # undef HAVE_GETHOSTBYNAME_R_6_ARG +@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + # define HAVE_GETHOSTBYNAME_R_3_ARG + # elif defined(__sun) || defined(__sgi) + # define HAVE_GETHOSTBYNAME_R_5_ARG +-# elif defined(linux) ++# elif defined(linux) && !__ANDROID__ + /* Rely on the configure script */ + # else + # undef HAVE_GETHOSTBYNAME_R +diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c +index 9223c99..1f8f625 100644 +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -3163,12 +3163,20 @@ static int + locale_error_handler(const char *errors, int *surrogateescape) + { + if (errors == NULL) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + + if (strcmp(errors, "strict") == 0) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + if (strcmp(errors, "surrogateescape") == 0) { +@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) + { + #ifdef HAVE_MBCS + return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) + { + #ifdef HAVE_MBCS + return PyUnicode_DecodeMBCS(s, size, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -4769,7 +4777,7 @@ onError: + return NULL; + } + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + + /* Simplified UTF-8 decoder using surrogateescape error handler, + used to decode the command line arguments on Mac OS X. +diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c +index 2f22209..ba42d84 100644 +--- a/Python/bltinmodule.c ++++ b/Python/bltinmodule.c +@@ -24,7 +24,7 @@ + #ifdef HAVE_MBCS + const char *Py_FileSystemDefaultEncoding = "mbcs"; + int Py_HasFileSystemDefaultEncoding = 1; +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + const char *Py_FileSystemDefaultEncoding = "utf-8"; + int Py_HasFileSystemDefaultEncoding = 1; + #else +diff --git a/Python/fileutils.c b/Python/fileutils.c +index bccd321..48ae1a5 100644 +--- a/Python/fileutils.c ++++ b/Python/fileutils.c +@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); + #include + #endif /* HAVE_FCNTL_H */ + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); + #endif + +@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) + Py_RETURN_NONE; + } + +-#if !defined(__APPLE__) && !defined(MS_WINDOWS) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) + extern int _Py_normalize_encoding(const char *, char *, size_t); + + /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. +@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) + } + #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ + +-#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) + static wchar_t* + decode_ascii_surrogateescape(const char *arg, size_t *size) + { +@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) + wchar_t* + Py_DecodeLocale(const char* arg, size_t *size) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + wchar_t *wstr; + wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); + if (size != NULL) { +@@ -423,7 +423,7 @@ oom: + char* + Py_EncodeLocale(const wchar_t *text, size_t *error_pos) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + Py_ssize_t len; + PyObject *unicode, *bytes = NULL; + char *cpath; +diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c +index 056bb76..c9d761e 100644 +--- a/Python/formatter_unicode.c ++++ b/Python/formatter_unicode.c +@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + { + switch (type) { + case LT_CURRENT_LOCALE: { ++#ifndef __ANDROID__ + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = PyUnicode_DecodeLocale( + locale_data->decimal_point, +@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + } + locale_info->grouping = locale_data->grouping; + break; ++#endif // __ANDROID__ + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); +diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c +index a17adf7..0843158 100644 +--- a/Python/pylifecycle.c ++++ b/Python/pylifecycle.c +@@ -224,6 +224,8 @@ get_locale_encoding(void) + return NULL; + } + return get_codec_name(codeset); ++#elif __ANDROID__ ++ return get_codec_name("UTF-8"); + #else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +diff --git a/Python/pystrtod.c b/Python/pystrtod.c +index 209c908..6bd792a 100644 +--- a/Python/pystrtod.c ++++ b/Python/pystrtod.c +@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) + + fail_pos = NULL; + ++#ifdef __ANDROID__ ++ decimal_point = "."; ++#else + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; ++#endif + decimal_point_len = strlen(decimal_point); + + assert(decimal_point_len != 0); +@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, + Py_LOCAL_INLINE(void) + change_decimal_from_locale_to_dot(char* buffer) + { ++#ifdef __ANDROID__ ++ const char *decimal_point = "."; ++#else + struct lconv *locale_data = localeconv(); + const char *decimal_point = locale_data->decimal_point; ++#endif + + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + size_t decimal_point_len = strlen(decimal_point); +diff --git a/configure b/configure +index e823a08..dc7c760 100755 +--- a/configure ++++ b/configure +@@ -5065,6 +5065,35 @@ fi + + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + ++# Test if we're running on Android. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 ++$as_echo_n "checking if target is Android-based... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++#if __ANDROID__ ++yes ++#endif ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "yes" >/dev/null 2>&1; then : ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ with_android=yes ++ ++else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ with_android=no ++ ++ ++fi ++rm -f conftest* ++ ++ + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 + $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } +@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +- INSTSONAME="$LDLIBRARY".$SOVERSION ++ if test "$with_android" != yes ++ then ++ INSTSONAME="$LDLIBRARY".$SOVERSION ++ else ++ INSTSONAME="LDLIBRARY" ++ fi ++ + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so +diff --git a/configure.ac b/configure.ac +index 56a73df..3245d87 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -726,6 +726,22 @@ fi + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + AC_SUBST(MULTIARCH) + ++# Test if we're running on Android. ++AC_MSG_CHECKING(if target is Android-based) ++AC_EGREP_CPP(yes, ++[ ++#if __ANDROID__ ++yes ++#endif ++], [ ++ AC_MSG_RESULT(yes) ++ with_android=yes ++ ], [ ++ AC_MSG_RESULT(no) ++ with_android=no ++ ] ++) ++ + AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) + cat >> conftest.c <type = *cp++; + spec->type = (spec->type == 'N') ? 'G' : 'g'; ++#ifdef __ANDROID__ ++ spec->dot = "."; ++ spec->sep = ","; ++ spec->grouping = "\3"; ++#else + lc = localeconv(); + spec->dot = lc->decimal_point; + spec->sep = lc->thousands_sep; + spec->grouping = lc->grouping; ++#endif + if (mpd_validate_lconv(spec) < 0) { + return 0; /* GCOV_NOT_REACHED */ + } +diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c +index b1d6add..2c6ec0e 100644 +--- a/Modules/_localemodule.c ++++ b/Modules/_localemodule.c +@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. + #include + #endif + ++#if __ANDROID__ ++/* Android's locale support is pretty much unusable, it's better to have the ++ higher-level module fall back to C locale emulation. */ ++#error "Android's locale support is too incomplete to create a usable module." ++#endif ++ ++ + PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); + + static PyObject *Error; +@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) + if (!result) + return NULL; + ++#ifdef __ANDROID__ ++ /* Don't even try on Android's broken locale.h. */ ++ goto failed; ++#else ++ + /* if LC_NUMERIC is different in the C library, use saved value */ + l = localeconv(); + +@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) + RESULT_INT(n_sign_posn); + return result; + ++#endif // __ANDROID__ ++ + failed: + Py_XDECREF(result); + return NULL; +diff --git a/Modules/main.c b/Modules/main.c +index 2a9ea28..e32f305 100644 +--- a/Modules/main.c ++++ b/Modules/main.c +@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) + oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, ""); + for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + /* Use utf-8 on Mac OS X */ + unicode = PyUnicode_FromString(p); + #else +diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c +index ec8c526..08e8021 100644 +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); + PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, + ULONG, struct _Py_stat_struct *); + #endif ++ ++/* Android doesn't expose AT_EACCESS - manually define it. */ ++#if !defined(AT_EACCESS) && defined(__ANDROID__) ++#define AT_EACCESS 0x200 ++#endif + + #ifdef MS_WINDOWS + static int +diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c +index 281c30b..28b93c2 100644 +--- a/Modules/pwdmodule.c ++++ b/Modules/pwdmodule.c +@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) + SETS(setIndex++, p->pw_passwd); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); + PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); ++#if !defined(__ANDROID__) + SETS(setIndex++, p->pw_gecos); ++#else ++ SETS(setIndex++, ""); ++#endif + SETS(setIndex++, p->pw_dir); + SETS(setIndex++, p->pw_shell); + +diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c +index ee24907..3718f70 100644 +--- a/Modules/socketmodule.c ++++ b/Modules/socketmodule.c +@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + On the other hand, not all Linux versions agree, so there the settings + computed by the configure script are needed! */ + +-#ifndef linux ++#if !defined(linux) || __ANDROID__ + # undef HAVE_GETHOSTBYNAME_R_3_ARG + # undef HAVE_GETHOSTBYNAME_R_5_ARG + # undef HAVE_GETHOSTBYNAME_R_6_ARG +@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ + # define HAVE_GETHOSTBYNAME_R_3_ARG + # elif defined(__sun) || defined(__sgi) + # define HAVE_GETHOSTBYNAME_R_5_ARG +-# elif defined(linux) ++# elif defined(linux) && !__ANDROID__ + /* Rely on the configure script */ + # else + # undef HAVE_GETHOSTBYNAME_R +diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c +index 9223c99..1f8f625 100644 +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -3163,12 +3163,20 @@ static int + locale_error_handler(const char *errors, int *surrogateescape) + { + if (errors == NULL) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + + if (strcmp(errors, "strict") == 0) { ++#ifdef __ANDROID__ ++ *surrogateescape = 1; ++#else + *surrogateescape = 0; ++#endif + return 0; + } + if (strcmp(errors, "surrogateescape") == 0) { +@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) + { + #ifdef HAVE_MBCS + return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) + { + #ifdef HAVE_MBCS + return PyUnicode_DecodeMBCS(s, size, NULL); +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); + #else + PyInterpreterState *interp = PyThreadState_GET()->interp; +@@ -4769,7 +4777,7 @@ onError: + return NULL; + } + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + + /* Simplified UTF-8 decoder using surrogateescape error handler, + used to decode the command line arguments on Mac OS X. +diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c +index 2f22209..ba42d84 100644 +--- a/Python/bltinmodule.c ++++ b/Python/bltinmodule.c +@@ -24,7 +24,7 @@ + #ifdef HAVE_MBCS + const char *Py_FileSystemDefaultEncoding = "mbcs"; + int Py_HasFileSystemDefaultEncoding = 1; +-#elif defined(__APPLE__) ++#elif defined(__APPLE__) || defined(__ANDROID__) + const char *Py_FileSystemDefaultEncoding = "utf-8"; + int Py_HasFileSystemDefaultEncoding = 1; + #else +diff --git a/Python/fileutils.c b/Python/fileutils.c +index bccd321..48ae1a5 100644 +--- a/Python/fileutils.c ++++ b/Python/fileutils.c +@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); + #include + #endif /* HAVE_FCNTL_H */ + +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); + #endif + +@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) + Py_RETURN_NONE; + } + +-#if !defined(__APPLE__) && !defined(MS_WINDOWS) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) + extern int _Py_normalize_encoding(const char *, char *, size_t); + + /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. +@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) + } + #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ + +-#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) ++#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) + static wchar_t* + decode_ascii_surrogateescape(const char *arg, size_t *size) + { +@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) + wchar_t* + Py_DecodeLocale(const char* arg, size_t *size) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + wchar_t *wstr; + wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); + if (size != NULL) { +@@ -423,7 +423,7 @@ oom: + char* + Py_EncodeLocale(const wchar_t *text, size_t *error_pos) + { +-#ifdef __APPLE__ ++#if defined(__APPLE__) || defined(__ANDROID__) + Py_ssize_t len; + PyObject *unicode, *bytes = NULL; + char *cpath; +diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c +index 056bb76..c9d761e 100644 +--- a/Python/formatter_unicode.c ++++ b/Python/formatter_unicode.c +@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + { + switch (type) { + case LT_CURRENT_LOCALE: { ++#ifndef __ANDROID__ + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = PyUnicode_DecodeLocale( + locale_data->decimal_point, +@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) + } + locale_info->grouping = locale_data->grouping; + break; ++#endif // __ANDROID__ + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = PyUnicode_FromOrdinal('.'); +diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c +index a17adf7..0843158 100644 +--- a/Python/pylifecycle.c ++++ b/Python/pylifecycle.c +@@ -224,6 +224,8 @@ get_locale_encoding(void) + return NULL; + } + return get_codec_name(codeset); ++#elif __ANDROID__ ++ return get_codec_name("UTF-8"); + #else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +diff --git a/Python/pystrtod.c b/Python/pystrtod.c +index 209c908..6bd792a 100644 +--- a/Python/pystrtod.c ++++ b/Python/pystrtod.c +@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) + + fail_pos = NULL; + ++#ifdef __ANDROID__ ++ decimal_point = "."; ++#else + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; ++#endif + decimal_point_len = strlen(decimal_point); + + assert(decimal_point_len != 0); +@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, + Py_LOCAL_INLINE(void) + change_decimal_from_locale_to_dot(char* buffer) + { ++#ifdef __ANDROID__ ++ const char *decimal_point = "."; ++#else + struct lconv *locale_data = localeconv(); + const char *decimal_point = locale_data->decimal_point; ++#endif + + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + size_t decimal_point_len = strlen(decimal_point); +diff --git a/configure b/configure +index e823a08..dc7c760 100755 +--- a/configure ++++ b/configure +@@ -5065,6 +5065,35 @@ fi + + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + ++# Test if we're running on Android. ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 ++$as_echo_n "checking if target is Android-based... " >&6; } ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++#if __ANDROID__ ++yes ++#endif ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "yes" >/dev/null 2>&1; then : ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ with_android=yes ++ ++else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ with_android=no ++ ++ ++fi ++rm -f conftest* ++ ++ + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 + $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } +@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h + LDLIBRARY='libpython$(LDVERSION).so' + BLDLIBRARY='-L. -lpython$(LDVERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +- INSTSONAME="$LDLIBRARY".$SOVERSION ++ if test "$with_android" != yes ++ then ++ INSTSONAME="$LDLIBRARY".$SOVERSION ++ else ++ INSTSONAME="LDLIBRARY" ++ fi ++ + if test "$with_pydebug" != yes + then + PY3LIBRARY=libpython3.so +diff --git a/configure.ac b/configure.ac +index 56a73df..3245d87 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -726,6 +726,22 @@ fi + MULTIARCH=$($CC --print-multiarch 2>/dev/null) + AC_SUBST(MULTIARCH) + ++# Test if we're running on Android. ++AC_MSG_CHECKING(if target is Android-based) ++AC_EGREP_CPP(yes, ++[ ++#if __ANDROID__ ++yes ++#endif ++], [ ++ AC_MSG_RESULT(yes) ++ with_android=yes ++ ], [ ++ AC_MSG_RESULT(no) ++ with_android=no ++ ] ++) ++ + AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) + cat >> conftest.c <GetStringUTFChars(env, j_name, &iscopy); ++ const char *value = (*env)->GetStringUTFChars(env, j_value, &iscopy); ++ setenv(name, value, 1); ++ (*env)->ReleaseStringUTFChars(env, j_name, name); ++ (*env)->ReleaseStringUTFChars(env, j_value, value); ++} ++ + + int Java_org_libsdl_app_SDLActivity_nativeAddJoystick( + JNIEnv* env, jclass jcls, From ae6b4099027be5d1883286d55f11db3f4dd9fd9d Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Tue, 22 Dec 2015 23:46:11 +0000 Subject: [PATCH 03/43] Terrible hacks to make python3 work --- pythonforandroid/archs.py | 2 + .../src/org/kivy/android/PythonActivity.java | 2 +- .../sdl2python3/build/jni/Application.mk | 2 +- pythonforandroid/build.py | 16 ++++- pythonforandroid/recipe.py | 58 +++++++++++++++---- .../recipes/hostpython3/__init__.py | 13 +++-- pythonforandroid/recipes/kivy/__init__.py | 6 +- pythonforandroid/recipes/pyjnius/__init__.py | 5 +- .../recipes/python3crystax/__init__.py | 3 + pythonforandroid/recipes/six/__init__.py | 2 +- 10 files changed, 83 insertions(+), 26 deletions(-) diff --git a/pythonforandroid/archs.py b/pythonforandroid/archs.py index 0a42713e60..774f23f71f 100644 --- a/pythonforandroid/archs.py +++ b/pythonforandroid/archs.py @@ -84,6 +84,8 @@ def get_env(self): env['AR'] = '{}-ar'.format(command_prefix) env['RANLIB'] = '{}-ranlib'.format(command_prefix) env['LD'] = '{}-ld'.format(command_prefix) + # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') + env['LDSHARED'] = env['LD'] env['STRIP'] = '{}-strip --strip-unneeded'.format(command_prefix) env['MAKE'] = 'make -j5' env['READELF'] = '{}-readelf'.format(command_prefix) diff --git a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java index 616b1b0097..7f754d868e 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java @@ -60,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", mFilesDirectory); SDLActivity.nativeSetEnv("ANDROID_APP_PATH", mFilesDirectory); SDLActivity.nativeSetEnv("PYTHONHOME", mFilesDirectory); - SDLActivity.nativeSetEnv("", mFilesDirectory + ":" + mFilesDirectory + "/lib"); + SDLActivity.nativeSetEnv("PYTHONPATH", mFilesDirectory + ":" + mFilesDirectory + "/lib"); // nativeSetEnv("ANDROID_ARGUMENT", getFilesDir()); diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk index 79b504d3f0..e79e378f94 100644 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk +++ b/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk @@ -4,4 +4,4 @@ # APP_STL := stlport_static # APP_ABI := armeabi armeabi-v7a x86 -APP_ABI := armeabi +APP_ABI := $(ARCH) diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py index 8cf6f1f20b..a146401e42 100644 --- a/pythonforandroid/build.py +++ b/pythonforandroid/build.py @@ -130,6 +130,14 @@ def ndk_ver(self, value): def ndk_is_crystax(self): return True if self.ndk_ver[:7] == 'crystax' else False + def ensure_crystax_python_install_dir(self): + dirn = self.get_python_install_dir() + ensure_dir(dirn) + ensure_dir(join(dirn, 'lib')) + sh.cp('-r', '/home/asandy/kivytest/crystax_stdlib', join(dirn, 'lib', 'python3.5')) + sh.cp('-r', '/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/libs/armeabi/modules', join(dirn, 'lib', 'python3.5', 'lib-dynload')) + ensure_dir(join(dirn, 'lib', 'site-packages')) + @property def sdk_dir(self): '''The path to the Android SDK.''' @@ -332,6 +340,7 @@ def prepare_build_environment(self, user_sdk_dir, user_ndk_dir, if cython: self.cython = cython break + self.cython = 'cython' if not self.cython: ok = False warning("Missing requirement: cython is not installed") @@ -476,6 +485,8 @@ def get_site_packages_dir(self, arch=None): # AND: This *must* be replaced with something more general in # order to support multiple python versions and/or multiple # archs. + if self.ndk_is_crystax: + return self.get_python_install_dir() return join(self.get_python_install_dir(), 'lib', 'python2.7', 'site-packages') @@ -549,7 +560,10 @@ def build_recipes(build_order, python_modules, ctx): # 4) biglink everything # AND: Should make this optional info_main('# Biglinking object files') - biglink(ctx, arch) + if not ctx.ndk_is_crystax: + biglink(ctx, arch) + else: + info('NDK is crystax, skipping biglink (will this work?)') # 5) postbuild packages info_main('# Postbuilding recipes') diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 7fbaa2bf03..e29bff0fbf 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -1,4 +1,4 @@ -from os.path import join, dirname, isdir, exists, isfile +from os.path import join, dirname, isdir, exists, isfile, split, realpath import importlib import zipfile import glob @@ -6,7 +6,7 @@ import sh import shutil -from os import listdir, unlink, environ, mkdir +from os import listdir, unlink, environ, mkdir, curdir from sys import stdout try: from urlparse import urlparse @@ -715,8 +715,30 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True): with current_directory(self.get_build_dir(arch.arch)): # hostpython = sh.Command(self.ctx.hostpython) hostpython = sh.Command(self.hostpython_location) + hostpython = sh.Command('python3.5') - if self.call_hostpython_via_targetpython: + + if self.ctx.ndk_is_crystax: + hppath = join(dirname(self.hostpython_location), 'Lib', + 'site-packages') + hpenv = env.copy() + if 'PYTHONPATH' in hpenv: + hpenv['PYTHONPATH'] = ':'.join([hppath] + + hpenv['PYTHONPATH'].split(':')) + else: + hpenv['PYTHONPATH'] = hppath + # hpenv['PYTHONHOME'] = self.ctx.get_python_install_dir() + # shprint(hostpython, 'setup.py', 'build', + # _env=hpenv, *self.setup_extra_args) + shprint(hostpython, 'setup.py', 'install', '-O2', + '--root={}'.format(self.ctx.get_python_install_dir()), + '--install-lib=lib/python3.5/site-packages', + _env=hpenv, *self.setup_extra_args) + site_packages_dir = self.ctx.get_site_packages_dir() + built_files = glob.glob(join('build', 'lib*', '*')) + for filen in built_files: + shprint(sh.cp, '-r', filen, join(site_packages_dir, split(filen)[-1])) + elif self.call_hostpython_via_targetpython: shprint(hostpython, 'setup.py', 'install', '-O2', _env=env, *self.setup_extra_args) else: @@ -793,8 +815,13 @@ def build_arch(self, arch): def build_cython_components(self, arch): info('Cythonizing anything necessary in {}'.format(self.name)) env = self.get_recipe_env(arch) + # env['PYTHONHOME'] = self.ctx.get_python_install_dir() + env['PYTHONPATH'] = '/usr/lib/python3.5/site-packages/:/usr/lib/python3.5' with current_directory(self.get_build_dir(arch.arch)): - hostpython = sh.Command(self.ctx.hostpython) + # hostpython = sh.Command(self.ctx.hostpython) + hostpython = sh.Command('python3.5') + shprint(hostpython, '-c', 'import sys; print(sys.path)', _env=env) + print('cwd is', realpath(curdir)) info('Trying first build of {} to get cython files: this is ' 'expected to fail'.format(self.name)) try: @@ -805,17 +832,19 @@ def build_cython_components(self, arch): info('{} first build failed (as expected)'.format(self.name)) info('Running cython where appropriate') + # shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', + # '-exec', self.ctx.cython, '{}', ';', _env=env) shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', - '-exec', self.ctx.cython, '{}', ';', _env=env) + '-exec', self.ctx.cython, '{}', ';') info('ran cython') shprint(hostpython, 'setup.py', 'build_ext', '-v', _env=env, _tail=20, _critical=True, *self.setup_extra_args) - print('stripping') - build_lib = glob.glob('./build/lib*') - shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', - env['STRIP'], '{}', ';', _env=env) + # print('stripping') + # build_lib = glob.glob('./build/lib*') + # shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', + # env['STRIP'], '{}', ';', _env=env) print('stripped!?') # exit(1) @@ -836,10 +865,12 @@ def build_cython_components(self, arch): def get_recipe_env(self, arch): env = super(CythonRecipe, self).get_recipe_env(arch) - env['LDFLAGS'] = env['LDFLAGS'] + ' -L{}'.format( + env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format( self.ctx.get_libs_dir(arch.arch) + - '-L{}'.format(self.ctx.libs_dir)) - env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + ' -L{} '.format(self.ctx.libs_dir)) + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2python3crystax/libs/armeabi ' + # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') + env['LDSHARED'] = env['CC'] + ' -shared' + shprint(sh.whereis, env['LDSHARED'], _env=env) env['LIBLINK'] = 'NOTNONE' env['NDKPLATFORM'] = self.ctx.ndk_platform @@ -849,4 +880,7 @@ def get_recipe_env(self, arch): 'objects_{}'.format(self.name)) env['LIBLINK_PATH'] = liblink_path ensure_dir(liblink_path) + + env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS'] + return env diff --git a/pythonforandroid/recipes/hostpython3/__init__.py b/pythonforandroid/recipes/hostpython3/__init__.py index e3fa119b81..666c083020 100644 --- a/pythonforandroid/recipes/hostpython3/__init__.py +++ b/pythonforandroid/recipes/hostpython3/__init__.py @@ -6,8 +6,9 @@ class Hostpython3Recipe(Recipe): - version = '3.4.2' - url = 'http://python.org/ftp/python/{version}/Python-{version}.tgz' + version = '3.5' + # url = 'http://python.org/ftp/python/{version}/Python-{version}.tgz' + url = 'https://github.com/crystax/android-vendor-python-3-5/archive/master.zip' name = 'hostpython3' conflicts = ['hostpython2'] @@ -17,13 +18,13 @@ class Hostpython3Recipe(Recipe): # shprint(sh.cp, join(self.get_recipe_dir(), 'Setup'), # join(self.get_build_dir('armeabi'), 'Modules', 'Setup')) - def build_armeabi(self): + def build_arch(self, arch): # AND: Should use an i386 recipe system warning('Running hostpython build. Arch is armeabi! ' 'This is naughty, need to fix the Arch system!') # AND: Fix armeabi again - with current_directory(self.get_build_dir('armeabi')): + with current_directory(self.get_build_dir(arch.arch)): if exists('hostpython'): info('hostpython already exists, skipping build') @@ -53,8 +54,8 @@ def build_armeabi(self): 'hostpython build! Exiting.') exit(1) - self.ctx.hostpython = join(self.get_build_dir('armeabi'), 'hostpython') - self.ctx.hostpgen = join(self.get_build_dir('armeabi'), 'hostpgen') + self.ctx.hostpython = join(self.get_build_dir(arch.arch), 'hostpython') + self.ctx.hostpgen = join(self.get_build_dir(arch.arch), 'hostpgen') recipe = Hostpython3Recipe() diff --git a/pythonforandroid/recipes/kivy/__init__.py b/pythonforandroid/recipes/kivy/__init__.py index 2430fa7aec..e89ce1067f 100644 --- a/pythonforandroid/recipes/kivy/__init__.py +++ b/pythonforandroid/recipes/kivy/__init__.py @@ -11,11 +11,13 @@ class KivyRecipe(CythonRecipe): url = 'https://github.com/kivy/kivy/archive/{version}.zip' name = 'kivy' - depends = [('sdl2', 'pygame'), 'pyjnius'] + depends = [('sdl2', 'pygame', 'sdl2python3crystax'), 'pyjnius'] + + # patches = ['setargv.patch'] def get_recipe_env(self, arch): env = super(KivyRecipe, self).get_recipe_env(arch) - if 'sdl2' in self.ctx.recipe_build_order: + if ('sdl2' in self.ctx.recipe_build_order or 'sdl2python3crystax' in self.ctx.recipe_build_order): env['USE_SDL2'] = '1' env['KIVY_SDL2_PATH'] = ':'.join([ join(self.ctx.bootstrap.build_dir, 'jni', 'SDL', 'include'), diff --git a/pythonforandroid/recipes/pyjnius/__init__.py b/pythonforandroid/recipes/pyjnius/__init__.py index 62d83bed00..31e85ed830 100644 --- a/pythonforandroid/recipes/pyjnius/__init__.py +++ b/pythonforandroid/recipes/pyjnius/__init__.py @@ -9,10 +9,11 @@ class PyjniusRecipe(CythonRecipe): version = 'master' url = 'https://github.com/kivy/pyjnius/archive/{version}.zip' name = 'pyjnius' - depends = ['python2', ('sdl2', 'sdl'), 'six'] + depends = [('python2', 'python3crystax'), ('sdl2', 'sdl', 'sdl2python3crystax'), 'six'] site_packages_name = 'jnius' - patches = [('sdl2_jnienv_getter.patch', will_build('sdl2'))] + patches = [('sdl2_jnienv_getter.patch', will_build('sdl2python3crystax')), + 'getenv.patch'] def postbuild_arch(self, arch): super(PyjniusRecipe, self).postbuild_arch(arch) diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py index 35c7612841..7b7b7bdd92 100644 --- a/pythonforandroid/recipes/python3crystax/__init__.py +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -18,6 +18,9 @@ def __init__(self, **kwargs): super(Python3Recipe, self).__init__(**kwargs) self.crystax = lambda *args: True if self.ctx.ndk_is_crystax else False + def prebuild_arch(self, arch): + self.ctx.ensure_crystax_python_install_dir() + def build_arch(self, arch): info('doing nothing, the crystax python3 is included in the ndk!') diff --git a/pythonforandroid/recipes/six/__init__.py b/pythonforandroid/recipes/six/__init__.py index c5ce72a7db..92b266f4ef 100644 --- a/pythonforandroid/recipes/six/__init__.py +++ b/pythonforandroid/recipes/six/__init__.py @@ -5,6 +5,6 @@ class SixRecipe(PythonRecipe): version = '1.9.0' url = 'https://pypi.python.org/packages/source/s/six/six-{version}.tar.gz' - depends = ['python2'] + depends = [('python2', 'python3crystax')] recipe = SixRecipe() From 90f681b93c00cde32f1851cb5ad4cca5cfddb72c Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Tue, 22 Dec 2015 23:46:23 +0000 Subject: [PATCH 04/43] Additions to test app for python3 --- tests/testapp_nogui/main.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/testapp_nogui/main.py b/tests/testapp_nogui/main.py index a0eeb00553..bb7506fb48 100644 --- a/tests/testapp_nogui/main.py +++ b/tests/testapp_nogui/main.py @@ -9,6 +9,20 @@ for i in range(45, 50): print(i, sqrt(i)) +print('trying to import six') +try: + import six +except ImportError: + print('import failed') + + +print('trying to import six again') +try: + import six +except ImportError: + print('import failed (again?)') +print('import six worked!') + print('Just printing stuff apparently worked, trying pyjnius') import jnius From 30cbb96025b6daafb10f85abfb15fb89f31bad32 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Wed, 23 Dec 2015 14:37:35 +0000 Subject: [PATCH 05/43] Possibly-silly function composition for patching --- pythonforandroid/patching.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/pythonforandroid/patching.py b/pythonforandroid/patching.py index 70d7e9c9cf..8b813e603e 100644 --- a/pythonforandroid/patching.py +++ b/pythonforandroid/patching.py @@ -1,22 +1,35 @@ from os import uname +class ComposableFunction(object): + def __init__(self, function): + self.func = function + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + def __and__(self, f): + return ComposableFunction(lambda *args, **kwargs: self(*args, **kwargs) and f(*args, **kwargs)) + + def __or__(self, f): + return ComposableFunction(lambda *args, **kwargs: self(*args, **kwargs) or f(*args, **kwargs)) + def check_all(*callables): def check(**kwargs): return all(c(**kwargs) for c in callables) - return check + return ComposableFunction(check) def check_any(*callables): def check(**kwargs): return any(c(**kwargs) for c in callables) - return check + return ComposableFunction(check) def is_platform(platform): def is_x(**kwargs): return uname()[0] == platform - return is_x + return ComposableFunction(is_x) is_linux = is_platform('Linux') is_darwin = is_platform('Darwin') @@ -25,43 +38,43 @@ def is_x(**kwargs): def is_arch(xarch): def is_x(arch, **kwargs): return arch.arch == xarch - return is_x + return ComposableFunction(is_x) def is_api_gt(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api > apiver - return is_x + return ComposableFunction(is_x) def is_api_gte(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api >= apiver - return is_x + return ComposableFunction(is_x) def is_api_lt(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api < apiver - return is_x + return ComposableFunction(is_x) def is_api_lte(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api <= apiver - return is_x + return ComposableFunction(is_x) def is_api(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api == apiver - return is_x + return ComposableFunction(is_x) def will_build(recipe_name): def will(recipe, **kwargs): return recipe_name in recipe.ctx.recipe_build_order - return will + return ComposableFunction(will) def is_ndk(ndk): From b6896a62d20f8f908fef9e18c855a1701a9445fe Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Wed, 23 Dec 2015 14:39:15 +0000 Subject: [PATCH 06/43] Removed ComposableFunction --- pythonforandroid/patching.py | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/pythonforandroid/patching.py b/pythonforandroid/patching.py index 8b813e603e..70d7e9c9cf 100644 --- a/pythonforandroid/patching.py +++ b/pythonforandroid/patching.py @@ -1,35 +1,22 @@ from os import uname -class ComposableFunction(object): - def __init__(self, function): - self.func = function - - def __call__(self, *args, **kwargs): - return self.func(*args, **kwargs) - - def __and__(self, f): - return ComposableFunction(lambda *args, **kwargs: self(*args, **kwargs) and f(*args, **kwargs)) - - def __or__(self, f): - return ComposableFunction(lambda *args, **kwargs: self(*args, **kwargs) or f(*args, **kwargs)) - def check_all(*callables): def check(**kwargs): return all(c(**kwargs) for c in callables) - return ComposableFunction(check) + return check def check_any(*callables): def check(**kwargs): return any(c(**kwargs) for c in callables) - return ComposableFunction(check) + return check def is_platform(platform): def is_x(**kwargs): return uname()[0] == platform - return ComposableFunction(is_x) + return is_x is_linux = is_platform('Linux') is_darwin = is_platform('Darwin') @@ -38,43 +25,43 @@ def is_x(**kwargs): def is_arch(xarch): def is_x(arch, **kwargs): return arch.arch == xarch - return ComposableFunction(is_x) + return is_x def is_api_gt(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api > apiver - return ComposableFunction(is_x) + return is_x def is_api_gte(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api >= apiver - return ComposableFunction(is_x) + return is_x def is_api_lt(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api < apiver - return ComposableFunction(is_x) + return is_x def is_api_lte(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api <= apiver - return ComposableFunction(is_x) + return is_x def is_api(apiver): def is_x(recipe, **kwargs): return recipe.ctx.android_api == apiver - return ComposableFunction(is_x) + return is_x def will_build(recipe_name): def will(recipe, **kwargs): return recipe_name in recipe.ctx.recipe_build_order - return ComposableFunction(will) + return will def is_ndk(ndk): From 9e96d2c248fc0da0aa7c284e68567e5a50fa1dc2 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Wed, 23 Dec 2015 14:41:30 +0000 Subject: [PATCH 07/43] Deleted patches in python3crystax --- .../recipes/python3crystax/log_failures.patch | 385 ------------ .../patches-termux/Lib-tmpfile.py.patch | 12 - .../patches-termux/_cursesmodule.c.patch | 15 - .../patches-termux/dlfcn_py_android.patch | 30 - .../patches-termux/mathmodule.c.patch | 47 -- .../patches-termux/posixmodule.c.patch | 100 --- .../pwdmodule_no_pw_gecos.patch | 16 - .../patches-termux/setup.py.patch | 23 - .../patches-termux/subprocess.py.patch | 12 - .../python-3.4.2-android-libmpdec.patch | 158 ----- .../patches/python-3.4.2-android-locale.patch | 255 -------- .../patches/python-3.4.2-android-misc.patch | 313 ---------- ...ndroid-missing-getdents64-definition.patch | 17 - .../patches/python-3.4.2-cross-compile.patch | 78 --- .../python-3.4.2-libpymodules_loader.patch | 42 -- .../patches/python-3.4.2-python-misc.patch | 86 --- .../python-3.5.0-android-locale.patch | 573 ----------------- .../python-3.5.0-android-misc.patch | 573 ----------------- .../python-3.5.0-define_macro.patch | 13 - ...python-3.5.0-locale_and_android_misc.patch | 586 ------------------ 20 files changed, 3334 deletions(-) delete mode 100644 pythonforandroid/recipes/python3crystax/log_failures.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-misc.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-define_macro.patch delete mode 100644 pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-locale_and_android_misc.patch diff --git a/pythonforandroid/recipes/python3crystax/log_failures.patch b/pythonforandroid/recipes/python3crystax/log_failures.patch deleted file mode 100644 index ec85035515..0000000000 --- a/pythonforandroid/recipes/python3crystax/log_failures.patch +++ /dev/null @@ -1,385 +0,0 @@ -diff --git a/Include/Python.h b/Include/Python.h -index 2dd8290..aab5810 100644 ---- a/Include/Python.h -+++ b/Include/Python.h -@@ -41,6 +41,12 @@ - #include - #endif - -+/* p4a log redirect */ -+#include -+#include "android/log.h" -+#define LOG(x) __android_log_write(ANDROID_LOG_INFO, "python", (x)) -+ -+ - /* CAUTION: Build setups should ensure that NDEBUG is defined on the - * compiler command line when building Python in release mode; else - * assert() calls won't be removed. -diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c -index 9bb3666..4fb89c5 100644 ---- a/Modules/gcmodule.c -+++ b/Modules/gcmodule.c -@@ -1758,13 +1758,14 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) - PyVarObject *op; - - if (nitems < 0) { -+ LOG("PyErr_BadInternalCall in gc"); - PyErr_BadInternalCall(); - return NULL; - } - size = _PyObject_VAR_SIZE(tp, nitems); - op = (PyVarObject *) _PyObject_GC_Malloc(size); - if (op != NULL) -- op = PyObject_INIT_VAR(op, tp, nitems); -+ op = PyObject_INIT_VAR(op, tp, nitems); - return op; - } - -diff --git a/Modules/getpath.c b/Modules/getpath.c -index c057737..5d02f08 100644 ---- a/Modules/getpath.c -+++ b/Modules/getpath.c -@@ -866,6 +866,7 @@ wchar_t * - Py_GetProgramFullPath(void) - { - if (!module_search_path) -+ LOG("Py_GetProgramFullPath: calculating path"); - calculate_path(); - return progpath; - } -diff --git a/Objects/floatobject.c b/Objects/floatobject.c -index 05b7679..be38e75 100644 ---- a/Objects/floatobject.c -+++ b/Objects/floatobject.c -@@ -77,6 +77,7 @@ PyFloat_GetInfo(void) - - floatinfo = PyStructSequence_New(&FloatInfoType); - if (floatinfo == NULL) { -+ LOG("PyFloat_GetInfo got NULL"); - return NULL; - } - -@@ -84,22 +85,63 @@ PyFloat_GetInfo(void) - PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag)) - #define SetDblFlag(flag) \ - PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag)) -+ -+ LOG("About to start typing to set int and dbl flags"); -+ if (PyErr_Occurred()) { -+ LOG("err even before 1!"); -+ } else { -+ LOG("no err before this"); -+ } - - SetDblFlag(DBL_MAX); -+ if (PyErr_Occurred()) { -+ LOG("err 1"); -+ } - SetIntFlag(DBL_MAX_EXP); -+ if (PyErr_Occurred()) { -+ LOG("err 2"); -+ } - SetIntFlag(DBL_MAX_10_EXP); -+ if (PyErr_Occurred()) { -+ LOG("err 3"); -+ } - SetDblFlag(DBL_MIN); -+ if (PyErr_Occurred()) { -+ LOG("err 4"); -+ } - SetIntFlag(DBL_MIN_EXP); -+ if (PyErr_Occurred()) { -+ LOG("err 5"); -+ } - SetIntFlag(DBL_MIN_10_EXP); -+ if (PyErr_Occurred()) { -+ LOG("err 6"); -+ } - SetIntFlag(DBL_DIG); -+ if (PyErr_Occurred()) { -+ LOG("err 7"); -+ } - SetIntFlag(DBL_MANT_DIG); -+ if (PyErr_Occurred()) { -+ LOG("err 8"); -+ } - SetDblFlag(DBL_EPSILON); -+ if (PyErr_Occurred()) { -+ LOG("err 9"); -+ } - SetIntFlag(FLT_RADIX); -+ if (PyErr_Occurred()) { -+ LOG("err 10"); -+ } - SetIntFlag(FLT_ROUNDS); -+ if (PyErr_Occurred()) { -+ LOG("err 11"); -+ } - #undef SetIntFlag - #undef SetDblFlag - - if (PyErr_Occurred()) { -+ LOG("PyErr_Occurred in floatinfo stuff"); - Py_CLEAR(floatinfo); - return NULL; - } -diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c -index d9c131c..0840930 100644 ---- a/Objects/unicodeobject.c -+++ b/Objects/unicodeobject.c -@@ -2297,6 +2297,12 @@ PyUnicode_AsUCS4Copy(PyObject *string) - PyObject * - PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - { -+ if (PyErr_Occurred()) { -+ LOG("PyErr already occurred before PyUnicode_FromWideChar does anything"); -+ } else { -+ LOG("start of PyUnicode_FromWideChar; everything seems fine"); -+ } -+ - if (w == NULL) { - if (size == 0) - _Py_RETURN_UNICODE_EMPTY(); -diff --git a/Python/errors.c b/Python/errors.c -index 996292a..20bc3f1 100644 ---- a/Python/errors.c -+++ b/Python/errors.c -@@ -755,6 +755,9 @@ PyErr_Format(PyObject *exception, const char *format, ...) - { - va_list vargs; - PyObject* string; -+ -+ LOG("PyErr Format with:"); -+ LOG(format); - - #ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -diff --git a/Python/pythonrun.c b/Python/pythonrun.c -index 0327830..e4428d0 100644 ---- a/Python/pythonrun.c -+++ b/Python/pythonrun.c -@@ -415,6 +415,7 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) - /* initialize builtin exceptions */ - _PyExc_Init(bimod); - -+ LOG("Got to _PySys_Init"); - sysmod = _PySys_Init(); - if (sysmod == NULL) - Py_FatalError("Py_Initialize: can't initialize sys"); -@@ -2594,6 +2595,8 @@ Py_FatalError(const char *msg) - { - const int fd = fileno(stderr); - PyThreadState *tstate; -+ -+ LOG(msg); - - fprintf(stderr, "Fatal Python error: %s\n", msg); - fflush(stderr); /* it helps in Windows debug build */ -diff --git a/Python/sysmodule.c b/Python/sysmodule.c -index 39fe53f..d76c793 100644 ---- a/Python/sysmodule.c -+++ b/Python/sysmodule.c -@@ -1633,27 +1633,36 @@ _PySys_Init(void) - int res; - - m = PyModule_Create(&sysmodule); -- if (m == NULL) -+ if (m == NULL) { -+ LOG("module create is NULL"); - return NULL; -+ } - sysdict = PyModule_GetDict(m); - #define SET_SYS_FROM_STRING_BORROW(key, value) \ - do { \ - PyObject *v = (value); \ -- if (v == NULL) \ -+ if (v == NULL) { \ -+ LOG("set from string 1 is NULL"); \ - return NULL; \ -+ } \ - res = PyDict_SetItemString(sysdict, key, v); \ - if (res < 0) { \ -+ LOG("_SetItemString thing was NULL"); \ - return NULL; \ - } \ - } while (0) - #define SET_SYS_FROM_STRING(key, value) \ - do { \ - PyObject *v = (value); \ -- if (v == NULL) \ -+ if (v == NULL) { \ -+ LOG("set from string 2 is NULL"); \ -+ LOG(key); \ - return NULL; \ -+ } \ - res = PyDict_SetItemString(sysdict, key, v); \ - Py_DECREF(v); \ - if (res < 0) { \ -+ LOG("_SetItemString 2 thing was NULL"); \ - return NULL; \ - } \ - } while (0) -@@ -1677,47 +1686,102 @@ _PySys_Init(void) - #endif - - /* stdin/stdout/stderr are now set by pythonrun.c */ -+ -+ if (PyErr_Occurred()) { -+ LOG("PyErr_Occurred before set_sys_from_string stuff"); -+ } else { -+ LOG("PyErr has *NOT* yet occurred before set_sys_from_string stuff"); -+ } - - SET_SYS_FROM_STRING_BORROW("__displayhook__", - PyDict_GetItemString(sysdict, "displayhook")); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after __displayhook__"); -+ } - SET_SYS_FROM_STRING_BORROW("__excepthook__", - PyDict_GetItemString(sysdict, "excepthook")); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after __excepthook__"); -+ } - SET_SYS_FROM_STRING("version", - PyUnicode_FromString(Py_GetVersion())); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after __excepthook__"); -+ } - SET_SYS_FROM_STRING("hexversion", - PyLong_FromLong(PY_VERSION_HEX)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after hexversion"); -+ } - SET_SYS_FROM_STRING("_mercurial", - Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), - _Py_hgversion())); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after _mercurial"); -+ } - SET_SYS_FROM_STRING("dont_write_bytecode", - PyBool_FromLong(Py_DontWriteBytecodeFlag)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after dont_write_bytecode"); -+ } - SET_SYS_FROM_STRING("api_version", - PyLong_FromLong(PYTHON_API_VERSION)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after api_version"); -+ } - SET_SYS_FROM_STRING("copyright", - PyUnicode_FromString(Py_GetCopyright())); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after copyright"); -+ } - SET_SYS_FROM_STRING("platform", - PyUnicode_FromString(Py_GetPlatform())); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after platform"); -+ } else { -+ LOG("No PyErr yet, about to do executable"); -+ } - SET_SYS_FROM_STRING("executable", - PyUnicode_FromWideChar( - Py_GetProgramFullPath(), -1)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after executable"); -+ } - SET_SYS_FROM_STRING("prefix", - PyUnicode_FromWideChar(Py_GetPrefix(), -1)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after prefix"); -+ } - SET_SYS_FROM_STRING("exec_prefix", - PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after exec_prefix"); -+ } - SET_SYS_FROM_STRING("base_prefix", - PyUnicode_FromWideChar(Py_GetPrefix(), -1)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after base_prefix"); -+ } - SET_SYS_FROM_STRING("base_exec_prefix", - PyUnicode_FromWideChar(Py_GetExecPrefix(), -1)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr after base_exec_prefix"); -+ } - SET_SYS_FROM_STRING("maxsize", - PyLong_FromSsize_t(PY_SSIZE_T_MAX)); -+ if (PyErr_Occurred()) { -+ LOG("PyErr_Occurred before float_info stuff"); -+ } - SET_SYS_FROM_STRING("float_info", - PyFloat_GetInfo()); - SET_SYS_FROM_STRING("int_info", - PyLong_GetInfo()); - /* initialize hash_info */ - if (Hash_InfoType.tp_name == NULL) { -- if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) -+ if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { -+ LOG("InitType2 thing was NULL"); - return NULL; -+ } - } - SET_SYS_FROM_STRING("hash_info", - get_hash_info()); -@@ -1745,8 +1809,10 @@ _PySys_Init(void) - #endif - if (warnoptions == NULL) { - warnoptions = PyList_New(0); -- if (warnoptions == NULL) -+ if (warnoptions == NULL) { -+ LOG("warnoptions is NULL"); - return NULL; -+ } - } - else { - Py_INCREF(warnoptions); -@@ -1758,8 +1824,10 @@ _PySys_Init(void) - /* version_info */ - if (VersionInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&VersionInfoType, -- &version_info_desc) < 0) -+ &version_info_desc) < 0) { -+ LOG("versioninfo stuff is NULL"); - return NULL; -+ } - } - version_info = make_version_info(); - SET_SYS_FROM_STRING("version_info", version_info); -@@ -1775,8 +1843,10 @@ _PySys_Init(void) - - /* flags */ - if (FlagsType.tp_name == 0) { -- if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) -+ if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) { -+ LOG("flags stuff is NULL"); - return NULL; -+ } - } - SET_SYS_FROM_STRING("flags", make_flags()); - /* prevent user from creating new instances */ -@@ -1790,8 +1860,10 @@ _PySys_Init(void) - /* getwindowsversion */ - if (WindowsVersionType.tp_name == 0) - if (PyStructSequence_InitType2(&WindowsVersionType, -- &windows_version_desc) < 0) -+ &windows_version_desc) < 0) { -+ LOG("Windows version is NULL"); - return NULL; -+ } - /* prevent user from creating new instances */ - WindowsVersionType.tp_init = NULL; - WindowsVersionType.tp_new = NULL; -@@ -1815,8 +1887,10 @@ _PySys_Init(void) - - #undef SET_SYS_FROM_STRING - #undef SET_SYS_FROM_STRING_BORROW -- if (PyErr_Occurred()) -+if (PyErr_Occurred()) { -+ LOG("PyErr_Occurred to NULL"); - return NULL; -+ } - return m; - } - diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch deleted file mode 100644 index ec6a2e80cf..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/Lib-tmpfile.py.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -u -r ../Python-3.4.3/Lib/tempfile.py ./Lib/tempfile.py ---- ../Python-3.4.3/Lib/tempfile.py 2015-02-25 06:27:44.000000000 -0500 -+++ ./Lib/tempfile.py 2015-07-21 19:58:07.631659902 -0400 -@@ -124,7 +124,7 @@ - if _os.name == 'nt': - dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) - else: -- dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) -+ dirlist.extend([ '@TERMUX_PREFIX@/tmp' ]) - - # As a last resort, the current directory. - try: diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch deleted file mode 100644 index b4740fd2b8..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/_cursesmodule.c.patch +++ /dev/null @@ -1,15 +0,0 @@ -We use libandroid-support when building Python, but Python does not -use LDFLAGS when building modules (and not much point in this case). - -diff -u -r ../Python-3.4.1/Modules/_cursesmodule.c ./Modules/_cursesmodule.c ---- ../Python-3.4.1/Modules/_cursesmodule.c 2014-05-19 07:19:39.000000000 +0200 -+++ ./Modules/_cursesmodule.c 2014-06-04 08:56:50.441097925 +0200 -@@ -121,7 +121,7 @@ - #include - #endif - --#ifdef HAVE_LANGINFO_H -+#if defined(HAVE_LANGINFO_H) && !defined(__ANDROID__) - #include - #endif - diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch b/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch deleted file mode 100644 index ea5992bf8f..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/dlfcn_py_android.patch +++ /dev/null @@ -1,30 +0,0 @@ -From https://github.com/kivy/python-for-android/blob/master/recipes/python/patches/fix-dlfcn.patch - -See https://github.com/kivy/python-for-android/issues/141 -diff -u -r ../Python-3.4.0rc1/Lib/plat-linux/DLFCN.py ./Lib/plat-linux/DLFCN.py ---- ../Python-3.4.0rc1/Lib/plat-linux/DLFCN.py 2014-02-10 23:51:49.000000000 +0100 -+++ ./Lib/plat-linux/DLFCN.py 2014-02-13 03:25:19.000000000 +0100 -@@ -74,10 +74,18 @@ - # Included from gnu/stubs.h - - # Included from bits/dlfcn.h -+ -+# PATCHED FOR ANDROID (the only supported symbols are): -+# enum { -+# RTLD_NOW = 0, -+# RTLD_LAZY = 1, -+# RTLD_LOCAL = 0, -+# RTLD_GLOBAL = 2, -+# }; - RTLD_LAZY = 0x00001 --RTLD_NOW = 0x00002 --RTLD_BINDING_MASK = 0x3 --RTLD_NOLOAD = 0x00004 --RTLD_GLOBAL = 0x00100 -+RTLD_NOW = 0x00000 -+RTLD_BINDING_MASK = 0x0 -+RTLD_NOLOAD = 0x00000 -+RTLD_GLOBAL = 0x00002 - RTLD_LOCAL = 0 --RTLD_NODELETE = 0x01000 -+RTLD_NODELETE = 0x00000 diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch deleted file mode 100644 index 7f611409b4..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/mathmodule.c.patch +++ /dev/null @@ -1,47 +0,0 @@ -The math module uses function pointers to math functions, which breaks -using the system libm on ARM since we compile with -mhard-float. - -diff -u -r ../Python-3.4.3/Modules/mathmodule.c ./Modules/mathmodule.c ---- ../Python-3.4.3/Modules/mathmodule.c 2015-02-25 06:27:46.000000000 -0500 -+++ ./Modules/mathmodule.c 2015-04-29 16:50:52.895371496 -0400 -@@ -727,7 +727,7 @@ - */ - - static PyObject * --math_1_to_whatever(PyObject *arg, double (*func) (double), -+math_1_to_whatever(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), - PyObject *(*from_double_func) (double), - int can_overflow) - { -@@ -765,7 +765,7 @@ - errno = ERANGE for overflow). */ - - static PyObject * --math_1a(PyObject *arg, double (*func) (double)) -+math_1a(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double)) - { - double x, r; - x = PyFloat_AsDouble(arg); -@@ -808,19 +808,19 @@ - */ - - static PyObject * --math_1(PyObject *arg, double (*func) (double), int can_overflow) -+math_1(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), int can_overflow) - { - return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); - } - - static PyObject * --math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) -+math_1_to_int(PyObject *arg, __NDK_FPABI_MATH__ double (*func) (double), int can_overflow) - { - return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); - } - - static PyObject * --math_2(PyObject *args, double (*func) (double, double), char *funcname) -+math_2(PyObject *args, __NDK_FPABI_MATH__ double (*func) (double, double), char *funcname) - { - PyObject *ox, *oy; - double x, y, r; diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch b/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch deleted file mode 100644 index ff00333301..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/posixmodule.c.patch +++ /dev/null @@ -1,100 +0,0 @@ -diff -u -r ../Python-3.4.1/Modules/posixmodule.c ./Modules/posixmodule.c ---- ../Python-3.4.1/Modules/posixmodule.c 2014-05-19 07:19:39.000000000 +0200 -+++ ./Modules/posixmodule.c 2014-06-25 21:42:11.191524129 +0200 -@@ -6048,7 +6048,7 @@ - if (_Py_set_inheritable(master_fd, 0, NULL) < 0) - goto posix_error; - --#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) -+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) && !defined(__ANDROID__) - ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ - ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ - #ifndef __hpux -@@ -9162,7 +9162,12 @@ - needed definitions in sys/statvfs.h */ - #define _SVID3 - #endif --#include -+#ifdef __ANDROID__ -+# include -+# define statvfs statfs -+#else -+# include -+#endif - - static PyObject* - _pystatvfs_fromstructstatvfs(struct statvfs st) { -@@ -9178,9 +9183,15 @@ - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); -+#ifdef __ANDROID__ -+ PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_bavail)); -+ PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flags)); -+ PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namelen)); -+#else - PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); -+#endif - #else - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); -@@ -9194,11 +9205,18 @@ - PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); -+#ifdef __ANDROID__ -+ PyStructSequence_SET_ITEM(v, 7, -+ PyLong_FromLongLong((PY_LONG_LONG) st.b_favail)); -+ PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flags)); -+ PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namelen)); -+#else - PyStructSequence_SET_ITEM(v, 7, - PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); - #endif -+#endif - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; -@@ -9221,7 +9239,11 @@ - if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) - return NULL; - Py_BEGIN_ALLOW_THREADS -+#ifdef __ANDROID__ -+ res = fstatfs(fd, &st); -+#else - res = fstatvfs(fd, &st); -+#endif - Py_END_ALLOW_THREADS - if (res != 0) - return posix_error(); -@@ -9232,7 +9254,13 @@ - - - #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) --#include -+#ifdef __ANDROID__ -+# include -+# define statvfs statfs -+#else -+# include -+#endif -+ - - PyDoc_STRVAR(posix_statvfs__doc__, - "statvfs(path)\n\n\ -@@ -9271,7 +9299,11 @@ - goto exit; - } - #endif -+#ifdef __ANDROID__ -+ result = fstatfs(path.fd, &st); -+#else - result = fstatvfs(path.fd, &st); -+#endif - } - else - #endif diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch b/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch deleted file mode 100644 index 4e4f44159b..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/pwdmodule_no_pw_gecos.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -u -r ../Python-3.4.0rc1/Modules/pwdmodule.c ./Modules/pwdmodule.c ---- ../Python-3.4.0rc1/Modules/pwdmodule.c 2014-02-10 23:51:50.000000000 +0100 -+++ ./Modules/pwdmodule.c 2014-02-13 02:16:12.000000000 +0100 -@@ -72,7 +72,12 @@ - SETS(setIndex++, p->pw_passwd); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -+#ifdef __ANDROID__ -+ SETS(setIndex++, Py_None); -+ Py_INCREF(Py_None); -+#else - SETS(setIndex++, p->pw_gecos); -+#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch deleted file mode 100644 index ed32d444b6..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/setup.py.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -u -r ../Python-3.4.1/setup.py ./setup.py ---- ../Python-3.4.1/setup.py 2014-05-19 07:19:40.000000000 +0200 -+++ ./setup.py 2014-06-04 11:12:26.776875501 +0200 -@@ -568,7 +568,8 @@ - libraries=math_libs) ) - - # time libraries: librt may be needed for clock_gettime() -- time_libs = [] -+ # math_libs is needed by floatsleep() -+ time_libs = list(math_libs) - lib = sysconfig.get_config_var('TIMEMODULE_LIB') - if lib: - time_libs.append(lib) -@@ -625,7 +626,8 @@ - missing.append('spwd') - - # select(2); not on ancient System V -- exts.append( Extension('select', ['selectmodule.c']) ) -+ # selectmodule.c calls the ceil(3) math function -+ exts.append( Extension('select', ['selectmodule.c'], libraries=math_libs) ) - - # Fred Drake's interface to the Python parser - exts.append( Extension('parser', ['parsermodule.c']) ) diff --git a/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch b/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch deleted file mode 100644 index 41d399ae74..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches-termux/subprocess.py.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -u -r ../Python-3.4.1/Lib/subprocess.py ./Lib/subprocess.py ---- ../Python-3.4.1/Lib/subprocess.py 2014-05-19 07:19:38.000000000 +0200 -+++ ./Lib/subprocess.py 2014-06-04 11:31:48.708843737 +0200 -@@ -1344,7 +1344,7 @@ - args = list(args) - - if shell: -- args = ["/bin/sh", "-c"] + args -+ args = ["/system/bin/sh", "-c"] + args - if executable: - args[0] = executable - diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch deleted file mode 100644 index 66ccf0870c..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-libmpdec.patch +++ /dev/null @@ -1,158 +0,0 @@ -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/basearith.c Python-3.3.5-android/Modules/_decimal/libmpdec/basearith.c ---- Python-3.3.5/Modules/_decimal/libmpdec/basearith.c 2014-03-09 09:40:25.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/basearith.c 2014-08-05 16:11:29.000000000 +0200 -@@ -32,7 +32,7 @@ - #include - #include - #include "constants.h" --#include "memory.h" -+#include "mpmemory.h" - #include "typearith.h" - #include "basearith.h" - -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/io.c Python-3.3.5-android/Modules/_decimal/libmpdec/io.c ---- Python-3.3.5/Modules/_decimal/libmpdec/io.c 2014-08-05 16:05:22.000000000 +0200 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/io.c 2014-08-05 16:11:42.000000000 +0200 -@@ -37,7 +37,7 @@ - #include - #include "bits.h" - #include "constants.h" --#include "memory.h" -+#include "mpmemory.h" - #include "typearith.h" - #include "io.h" - -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/memory.c Python-3.3.5-android/Modules/_decimal/libmpdec/memory.c ---- Python-3.3.5/Modules/_decimal/libmpdec/memory.c 2014-03-09 09:40:25.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/memory.c 2014-08-05 16:11:52.000000000 +0200 -@@ -30,7 +30,7 @@ - #include - #include - #include "typearith.h" --#include "memory.h" -+#include "mpmemory.h" - - - /* Guaranteed minimum allocation for a coefficient. May be changed once -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/memory.h Python-3.3.5-android/Modules/_decimal/libmpdec/memory.h ---- Python-3.3.5/Modules/_decimal/libmpdec/memory.h 2014-03-09 09:40:25.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/memory.h 1970-01-01 01:00:00.000000000 +0100 -@@ -1,51 +0,0 @@ --/* -- * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * -- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND -- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- * SUCH DAMAGE. -- */ -- -- --#ifndef MEMORY_H --#define MEMORY_H -- -- --#include "mpdecimal.h" -- -- --/* Internal header file: all symbols have local scope in the DSO */ --MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) -- -- --int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); --int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); --int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); -- -- --MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -- -- --#endif -- -- -- -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/mpdecimal.c Python-3.3.5-android/Modules/_decimal/libmpdec/mpdecimal.c ---- Python-3.3.5/Modules/_decimal/libmpdec/mpdecimal.c 2014-03-09 09:40:25.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/mpdecimal.c 2014-08-05 16:12:06.000000000 +0200 -@@ -36,7 +36,7 @@ - #include "bits.h" - #include "convolute.h" - #include "crt.h" --#include "memory.h" -+#include "mpmemory.h" - #include "typearith.h" - #include "umodarith.h" - -diff -Nru Python-3.3.5/Modules/_decimal/libmpdec/mpmemory.h Python-3.3.5-android/Modules/_decimal/libmpdec/mpmemory.h ---- Python-3.3.5/Modules/_decimal/libmpdec/mpmemory.h 1970-01-01 01:00:00.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/mpmemory.h 2014-08-05 16:10:00.000000000 +0200 -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+ -+#ifndef MEMORY_H -+#define MEMORY_H -+ -+ -+#include "mpdecimal.h" -+ -+ -+/* Internal header file: all symbols have local scope in the DSO */ -+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) -+ -+ -+int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); -+int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status); -+int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status); -+ -+ -+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ -+ -+ -+#endif -+ -+ -+ diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch deleted file mode 100644 index 27ddcbbd3f..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-locale.patch +++ /dev/null @@ -1,255 +0,0 @@ -diff -ru Python-3.3.5/Modules/Setup.dist Python-3.3.5-android/Modules/Setup.dist ---- Python-3.3.5/Modules/Setup.dist 2014-03-09 09:40:23.000000000 +0100 -+++ Python-3.3.5-android/Modules/Setup.dist 2014-08-04 22:16:29.000000000 +0200 -@@ -118,7 +118,7 @@ - itertools itertoolsmodule.c # Functions creating iterators for efficient looping - - # access to ISO C locale support --_locale _localemodule.c # -lintl -+#_locale _localemodule.c # -lintl - - # Standard I/O baseline - _io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c -diff -ru Python-3.3.5/Modules/_decimal/libmpdec/io.c Python-3.3.5-android/Modules/_decimal/libmpdec/io.c ---- Python-3.3.5/Modules/_decimal/libmpdec/io.c 2014-03-09 09:40:25.000000000 +0100 -+++ Python-3.3.5-android/Modules/_decimal/libmpdec/io.c 2014-08-04 22:16:29.000000000 +0200 -@@ -868,10 +868,17 @@ - } - spec->type = *cp++; - spec->type = (spec->type == 'N') ? 'G' : 'g'; -+#ifdef __ANDROID__ -+ spec->dot = "."; -+ spec->sep = ","; -+ spec->grouping = "\3"; -+#else - lc = localeconv(); - spec->dot = lc->decimal_point; - spec->sep = lc->thousands_sep; - spec->grouping = lc->grouping; -+#endif -+ - if (mpd_validate_lconv(spec) < 0) { - return 0; /* GCOV_NOT_REACHED */ - } -diff -ru Python-3.3.5/Modules/_localemodule.c Python-3.3.5-android/Modules/_localemodule.c ---- Python-3.3.5/Modules/_localemodule.c 2014-03-09 09:40:26.000000000 +0100 -+++ Python-3.3.5-android/Modules/_localemodule.c 2014-08-04 22:16:29.000000000 +0200 -@@ -38,6 +38,13 @@ - #include - #endif - -+#if __ANDROID__ -+/* Android's locale support is pretty much unusable, it's better to have the -+ higher-level module fall back to C locale emulation. */ -+#error "Android's locale support is too incomplete to create a usable module." -+#endif -+ -+ - PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); - - static PyObject *Error; -@@ -141,6 +148,11 @@ - if (!result) - return NULL; - -+#ifdef __ANDROID__ -+ /* Don't even try on Android's broken locale.h. */ -+ goto failed; -+#else -+ - /* if LC_NUMERIC is different in the C library, use saved value */ - l = localeconv(); - -@@ -189,6 +201,7 @@ - RESULT_INT(p_sign_posn); - RESULT_INT(n_sign_posn); - return result; -+#endif // __ANDROID__ - - failed: - Py_XDECREF(result); -diff -ru Python-3.3.5/Modules/main.c Python-3.3.5-android/Modules/main.c ---- Python-3.3.5/Modules/main.c 2014-03-09 09:40:27.000000000 +0100 -+++ Python-3.3.5-android/Modules/main.c 2014-08-04 22:16:29.000000000 +0200 -@@ -522,7 +522,7 @@ - oldloc = strdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - /* Use utf-8 on Mac OS X */ - unicode = PyUnicode_FromString(p); - #else -diff -ru Python-3.3.5/Objects/unicodeobject.c Python-3.3.5-android/Objects/unicodeobject.c ---- Python-3.3.5/Objects/unicodeobject.c 2014-03-09 09:40:30.000000000 +0100 -+++ Python-3.3.5-android/Objects/unicodeobject.c 2014-08-04 22:16:29.000000000 +0200 -@@ -3295,13 +3295,22 @@ - static int - locale_error_handler(const char *errors, int *surrogateescape) - { -+ - if (errors == NULL) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - - if (strcmp(errors, "strict") == 0) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - if (strcmp(errors, "surrogateescape") == 0) { -@@ -3429,7 +3438,7 @@ - { - #ifdef HAVE_MBCS - return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -3709,7 +3718,7 @@ - { - #ifdef HAVE_MBCS - return PyUnicode_DecodeMBCS(s, size, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -4835,7 +4844,7 @@ - return NULL; - } - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - - /* Simplified UTF-8 decoder using surrogateescape error handler, - used to decode the command line arguments on Mac OS X. -diff -ru Python-3.3.5/Python/bltinmodule.c Python-3.3.5-android/Python/bltinmodule.c ---- Python-3.3.5/Python/bltinmodule.c 2014-03-09 09:40:32.000000000 +0100 -+++ Python-3.3.5-android/Python/bltinmodule.c 2014-08-04 22:16:29.000000000 +0200 -@@ -24,7 +24,7 @@ - #ifdef HAVE_MBCS - const char *Py_FileSystemDefaultEncoding = "mbcs"; - int Py_HasFileSystemDefaultEncoding = 1; --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - const char *Py_FileSystemDefaultEncoding = "utf-8"; - int Py_HasFileSystemDefaultEncoding = 1; - #else -diff -ru Python-3.3.5/Python/fileutils.c Python-3.3.5-android/Python/fileutils.c ---- Python-3.3.5/Python/fileutils.c 2014-03-09 09:40:32.000000000 +0100 -+++ Python-3.3.5-android/Python/fileutils.c 2014-08-04 22:16:29.000000000 +0200 -@@ -10,7 +10,7 @@ - #include - #endif - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); - #endif - -@@ -44,7 +44,7 @@ - Py_RETURN_NONE; - } - --#if !defined(__APPLE__) && !defined(MS_WINDOWS) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) - extern int _Py_normalize_encoding(const char *, char *, size_t); - - /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. -@@ -194,7 +194,7 @@ - } - #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ - --#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) - static wchar_t* - decode_ascii_surrogateescape(const char *arg, size_t *size) - { -@@ -241,7 +241,7 @@ - wchar_t* - _Py_char2wchar(const char* arg, size_t *size) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - wchar_t *wstr; - wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); - if (size != NULL) { -@@ -384,7 +384,7 @@ - char* - _Py_wchar2char(const wchar_t *text, size_t *error_pos) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - Py_ssize_t len; - PyObject *unicode, *bytes = NULL; - char *cpath; -diff -ru Python-3.3.5/Python/formatter_unicode.c Python-3.3.5-android/Python/formatter_unicode.c ---- Python-3.3.5/Python/formatter_unicode.c 2014-03-09 09:40:32.000000000 +0100 -+++ Python-3.3.5-android/Python/formatter_unicode.c 2014-08-04 22:16:29.000000000 +0200 -@@ -665,6 +665,7 @@ - { - switch (type) { - case LT_CURRENT_LOCALE: { -+#ifndef __ANDROID__ - struct lconv *locale_data = localeconv(); - locale_info->decimal_point = PyUnicode_DecodeLocale( - locale_data->decimal_point, -@@ -680,6 +681,7 @@ - } - locale_info->grouping = locale_data->grouping; - break; -+#endif // __ANDROID__ - } - case LT_DEFAULT_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); -diff -ru Python-3.3.5/Python/pystrtod.c Python-3.3.5-android/Python/pystrtod.c ---- Python-3.3.5/Python/pystrtod.c 2014-03-09 09:40:33.000000000 +0100 -+++ Python-3.3.5-android/Python/pystrtod.c 2014-08-04 22:16:29.000000000 +0200 -@@ -177,8 +177,12 @@ - - fail_pos = NULL; - -+#ifdef __ANDROID__ -+ decimal_point = "."; -+#else - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; -+#endif - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); -@@ -378,8 +382,12 @@ - Py_LOCAL_INLINE(void) - change_decimal_from_locale_to_dot(char* buffer) - { -+#ifdef __ANDROID__ -+ const char *decimal_point = "."; -+#else - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; -+#endif - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); -diff -ru Python-3.3.5/Python/pythonrun.c Python-3.3.5-android/Python/pythonrun.c ---- Python-3.3.5/Python/pythonrun.c 2014-03-09 09:40:33.000000000 +0100 -+++ Python-3.3.5-android/Python/pythonrun.c 2014-08-04 22:16:29.000000000 +0200 -@@ -188,6 +188,8 @@ - return NULL; - } - return get_codec_name(codeset); -+#elif __ANDROID__ -+ return get_codec_name("UTF-8"); - #else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch deleted file mode 100644 index 4d8fc395c7..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-misc.patch +++ /dev/null @@ -1,313 +0,0 @@ -diff -ru Python-3.3.5/Lib/platform.py Python-3.3.5-android/Lib/platform.py ---- Python-3.3.5/Lib/platform.py 2014-03-09 09:40:13.000000000 +0100 -+++ Python-3.3.5-android/Lib/platform.py 2014-08-04 22:19:36.000000000 +0200 -@@ -368,6 +368,63 @@ - supported_dists=supported_dists, - full_distribution_name=0) - -+_android_environment_vars = ( -+ 'ANDROID_PRIVATE', 'ANDROID_ARGUMENT', 'ANDROID_APP_PATH', 'ANDROID_DATA', -+ 'ANDROID_PROPERTY_WORKSPACE', 'ANDROID_BOOTLOGO') -+_android_version_property = 'ro.build.version.release' -+_android_buildstr_property = 'ro.build.version.full' -+ -+def android_version(version='', buildstr=''): -+ """ Attempt to get the Android version number and build string. -+ -+ The function checks for the getprop binary to retrieve build info, -+ and falls back to manually reading /system/build.prop if available. -+ -+ Returns a (version, buildstr) tuple which defaults to the args given -+ as parameters. -+ """ -+ if not any(os.getenv(e) for e in _android_environment_vars): -+ # Probably not on Android... -+ return version, buildstr -+ -+ version_obtained = False -+ buildstr_obtained = False -+ -+ # Try the 'official' API tool first, since /system/build.prop might -+ # not be the only source for properties. -+ if os.access('/system/bin/getprop', os.X_OK): -+ try: -+ output = subprocess.check_output(['/system/bin/getprop', -+ _android_version_property]) -+ version = output.decode('ascii').strip() -+ version_obtained = True -+ except (subprocess.CalledProcessError, UnicodeDecodeError): -+ pass -+ -+ try: -+ output = subprocess.check_output(['/system/bin/getprop', -+ _android_buildstr_property]) -+ buildstr = output.decode('ascii').strip() -+ buildstr_obtained = True -+ except (subprocess.CalledProcessError, UnicodeDecodeError): -+ pass -+ done = version_obtained and buildstr_obtained -+ -+ # Fall back to parsing /system/build.prop manually. -+ if not done and os.path.isfile('/system/build.prop'): -+ for line in open('/system/build.prop'): -+ if '=' not in line: -+ continue -+ key, val = line.split('=') -+ key = key.strip() -+ -+ if not version_obtained and key == _android_version_property: -+ version = val.strip() -+ elif not buildstr_obtained and key == _android_buildstr_property: -+ buildstr = val.strip() -+ -+ return version, buildstr -+ - def popen(cmd, mode='r', bufsize=-1): - - """ Portable popen() interface. -diff -ru Python-3.3.5/Lib/subprocess.py Python-3.3.5-android/Lib/subprocess.py ---- Python-3.3.5/Lib/subprocess.py 2014-03-09 09:40:13.000000000 +0100 -+++ Python-3.3.5-android/Lib/subprocess.py 2014-08-04 22:19:36.000000000 +0200 -@@ -1343,9 +1343,18 @@ - args = list(args) - - if shell: -- args = ["/bin/sh", "-c"] + args - if executable: -- args[0] = executable -+ main = executable -+ elif os.path.isfile('/bin/sh'): -+ main = '/bin/sh' -+ else: -+ import platform -+ if platform.android_version()[0]: -+ main = '/system/bin/sh' -+ else: -+ raise RuntimeError('Could not find system shell') -+ -+ args = [main, "-c"] + args - - if executable is None: - executable = args[0] -diff -ru Python-3.3.5/Lib/test/test_subprocess.py Python-3.3.5-android/Lib/test/test_subprocess.py ---- Python-3.3.5/Lib/test/test_subprocess.py 2014-03-09 09:40:19.000000000 +0100 -+++ Python-3.3.5-android/Lib/test/test_subprocess.py 2014-08-04 22:19:36.000000000 +0200 -@@ -17,6 +17,7 @@ - import shutil - import gc - import textwrap -+import platform - - try: - import resource -@@ -1356,7 +1357,10 @@ - fd, fname = mkstemp() - # reopen in text mode - with open(fd, "w", errors="surrogateescape") as fobj: -- fobj.write("#!/bin/sh\n") -+ if platform.android_version()[0]: -+ fobj.write('#!/system/bin/sh\n') -+ else: -+ fobj.write("#!/bin/sh\n") - fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.chmod(fname, 0o700) -@@ -1401,7 +1405,10 @@ - fd, fname = mkstemp() - # reopen in text mode - with open(fd, "w", errors="surrogateescape") as fobj: -- fobj.write("#!/bin/sh\n") -+ if platform.android_version()[0]: -+ fobj.write('#!/system/bin/sh\n') -+ else: -+ fobj.write("#!/bin/sh\n") - fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.chmod(fname, 0o700) -diff -ru Python-3.4.2/Modules/pwdmodule.c Python-3.4.2-android/Modules/pwdmodule.c ---- Python-3.4.2/Modules/pwdmodule.c 2015-02-24 23:06:31.000000000 +0100 -+++ Python-3.4.2-android/Modules/pwdmodule.c 2015-02-24 23:09:14.000000000 +0100 -@@ -72,7 +72,11 @@ - SETS(setIndex++, p->pw_passwd); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -+#if !defined(__ANDROID__) - SETS(setIndex++, p->pw_gecos); -+#else -+ SETS(setIndex++, ""); -+#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - -diff -ru Python-3.3.5/Modules/socketmodule.c Python-3.3.5-android/Modules/socketmodule.c ---- Python-3.3.5/Modules/socketmodule.c 2014-03-09 09:40:28.000000000 +0100 -+++ Python-3.3.5-android/Modules/socketmodule.c 2014-08-04 22:19:36.000000000 +0200 -@@ -150,7 +150,7 @@ - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - --#ifndef linux -+#if !defined(linux) || __ANDROID__ - # undef HAVE_GETHOSTBYNAME_R_3_ARG - # undef HAVE_GETHOSTBYNAME_R_5_ARG - # undef HAVE_GETHOSTBYNAME_R_6_ARG -@@ -169,7 +169,7 @@ - # define HAVE_GETHOSTBYNAME_R_3_ARG - # elif defined(__sun) || defined(__sgi) - # define HAVE_GETHOSTBYNAME_R_5_ARG --# elif defined(linux) -+# elif defined(linux) && !__ANDROID__ - /* Rely on the configure script */ - # else - # undef HAVE_GETHOSTBYNAME_R -diff -ru Python-3.3.5/Modules/posixmodule.c Python-3.3.5-android/Modules/posixmodule.c ---- Python-3.3.5/Modules/posixmodule.c 2014-03-09 08:40:28.000000000 +0000 -+++ Python-3.3.5-android/Modules/posixmodule.c 2015-02-24 19:57:05.368843433 +0000 -@@ -403,6 +403,11 @@ - #endif - #endif - -+/* Android doesn't expose AT_EACCESS - manually define it. */ -+#if !defined(AT_EACCESS) && defined(__ANDROID__) -+#define AT_EACCESS 0x200 -+#endif -+ - - #ifdef MS_WINDOWS - static int -diff -ru Python-3.3.5/Python/pytime.c Python-3.3.5-android/Python/pytime.c ---- Python-3.3.5/Python/pytime.c 2015-02-23 11:54:25.000000000 -0500 -+++ Python-3.3.5-android/Python/pytime.c 2015-02-23 11:55:19.000000000 -0500 -@@ -3,7 +3,7 @@ - #include - #endif - --#if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) -+#if (defined(__APPLE__) || defined(__ANDROID__)) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) - /* - * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter - * might fail on some platforms. This fallback is unwanted on MacOSX because -diff -ru Python-3.4.2/configure Python-3.4.2-android/configure ---- Python-3.4.2/configure 2015-02-24 23:18:31.000000000 +0100 -+++ Python-3.4.2-android/configure 2015-03-01 20:15:02.000000000 +0100 -@@ -5406,6 +5406,34 @@ - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - - -+# Test if we're running on Android. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 -+$as_echo_n "checking if target is Android-based... " >&6; } -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+#if __ANDROID__ -+yes -+#endif -+ -+_ACEOF -+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -+ $EGREP "yes" >/dev/null 2>&1; then : -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ with_android=yes -+ -+else -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ with_android=no -+ -+ -+fi -+rm -f conftest* -+ - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5 -@@ -5650,7 +5678,14 @@ - SOVERSION=`echo $SOVERSION|cut -d "." -f 1` - ;; - esac -- INSTSONAME="$LDLIBRARY".$SOVERSION -+ -+ if test "$with_android" != yes -+ then -+ INSTSONAME="$LDLIBRARY".$SOVERSION -+ else -+ INSTSONAME="$LDLIBRARY" -+ fi -+ - if test "$with_pydebug" != yes - then - PY3LIBRARY=libpython3.so -diff -ru Python-3.4.2/configure.ac Python-3.4.2-android/configure.ac ---- Python-3.4.2/configure.ac 2015-02-24 23:18:31.000000000 +0100 -+++ Python-3.4.2-android/configure.ac 2015-03-01 20:14:54.000000000 +0100 -@@ -796,6 +796,21 @@ - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - AC_SUBST(MULTIARCH) - -+# Test if we're running on Android. -+AC_MSG_CHECKING(if target is Android-based) -+AC_EGREP_CPP(yes, -+[ -+#if __ANDROID__ -+yes -+#endif -+], [ -+ AC_MSG_RESULT(yes) -+ with_android=yes -+ ], [ -+ AC_MSG_RESULT(no) -+ with_android=no -+ ] -+) - - AC_SUBST(LIBRARY) - AC_MSG_CHECKING(LIBRARY) -@@ -970,7 +985,14 @@ - SOVERSION=`echo $SOVERSION|cut -d "." -f 1` - ;; - esac -- INSTSONAME="$LDLIBRARY".$SOVERSION -+ -+ if test "$with_android" != yes -+ then -+ INSTSONAME="$LDLIBRARY".$SOVERSION -+ else -+ INSTSONAME="$LDLIBRARY" -+ fi -+ - if test "$with_pydebug" != yes - then - PY3LIBRARY=libpython3.so - -diff -ru Python-3.4.2/Makefile.pre.in Python-3.4.2-android/Makefile.pre.in ---- Python-3.4.2/Makefile.pre.in 2015-03-04 16:25:36.000000000 +0100 -+++ Python-3.4.2-android/Makefile.pre.in 2015-03-04 16:27:27.000000000 +0100 -@@ -568,7 +568,7 @@ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED) -lpython$(LDVERSION)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - -diff -Nru Python-3.4.2/Makefile.pre.in Python-3.4.2-android/Makefile.pre.in ---- Python-3.4.2/Makefile.pre.in 2015-06-27 17:04:23.885777456 +0000 -+++ Python-3.4.2-android/Makefile.pre.in 2015-06-27 17:05:27.709777315 +0000 -@@ -585,11 +585,9 @@ - $(RANLIB) $@ - - libpython$(LDVERSION).so: $(LIBRARY_OBJS) -+ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - if test $(INSTSONAME) != $(LDLIBRARY); then \ -- $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - $(LN) -f $(INSTSONAME) $@; \ -- else \ -- $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - fi - - libpython3.so: libpython$(LDVERSION).so diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch deleted file mode 100644 index 2bfcf6925d..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-android-missing-getdents64-definition.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -ru Python-3.3.5/Modules/_posixsubprocess.c Python-3.3.5-android/Modules/_posixsubprocess.c ---- Python-3.3.5/Modules/_posixsubprocess.c 2014-03-09 09:40:26.000000000 +0100 -+++ Python-3.3.5-android/Modules/_posixsubprocess.c 2014-08-04 22:19:36.000000000 +0200 -@@ -18,6 +18,12 @@ - #include - #endif - -+#if defined(__ANDROID__) -+/* Android doesn't expose syscalls. Let's add the definition manually. */ -+# include -+# define SYS_getdents64 __NR_getdents64 -+#endif -+ - #if defined(sun) - /* readdir64 is used to work around Solaris 9 bug 6395699. */ - # define readdir readdir64 - diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch deleted file mode 100644 index 7bceb49180..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-cross-compile.patch +++ /dev/null @@ -1,78 +0,0 @@ -diff -ru Python-3.3.5/Makefile.pre.in Python-3.3.5-android/Makefile.pre.in ---- Python-3.3.5/Makefile.pre.in 2014-03-09 09:40:23.000000000 +0100 -+++ Python-3.3.5-android/Makefile.pre.in 2014-08-04 22:13:00.000000000 +0200 -@@ -674,7 +674,7 @@ - $(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS) - @$(MKDIR_P) Include - $(MAKE) $(PGEN) -- $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) -+ $(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) - $(GRAMMAR_C): $(GRAMMAR_H) $(GRAMMAR_INPUT) $(PGENSRCS) - $(MAKE) $(GRAMMAR_H) - touch $(GRAMMAR_C) -@@ -1243,6 +1243,7 @@ - # Install the dynamically loadable modules - # This goes into $(exec_prefix) - sharedinstall: sharedmods -+ CC='$(CC)' LDSHARED='$(BLDSHARED)' LDFLAGS='$(LDFLAGS)' OPT='$(OPT)' CROSS_COMPILE='$(CROSS_COMPILE)' \ - $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ - --prefix=$(prefix) \ - --install-scripts=$(BINDIR) \ -diff -ru Python-3.3.5/configure Python-3.3.5-android/configure ---- Python-3.3.5/configure 2014-03-09 09:40:34.000000000 +0100 -+++ Python-3.3.5-android/configure 2014-08-04 22:13:00.000000000 +0200 -@@ -2943,13 +2943,18 @@ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python interpreter for cross build" >&5 - $as_echo_n "checking for python interpreter for cross build... " >&6; } - if test -z "$PYTHON_FOR_BUILD"; then -- for interp in python$PACKAGE_VERSION python3 python; do -- which $interp >/dev/null 2>&1 || continue -- if $interp -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then -- break -- fi -- interp= -- done -+ if test ! -z "$HOSTPYTHON" && PYTHONPATH="$ac_abs_confdir/Lib" "$HOSTPYTHON" -S -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then -+ interp="$HOSTPYTHON" -+ else -+ for interp in python$PACKAGE_VERSION python3 python; do -+ which $interp >/dev/null 2>&1 || continue -+ if $interp -c 'import sys;sys.exit(not sys.version_info[:2] >= (3,3))'; then -+ break -+ fi -+ interp= -+ done -+ fi -+ - if test x$interp = x; then - as_fn_error $? "python$PACKAGE_VERSION interpreter not found" "$LINENO" 5 - fi -diff -ru Python-3.3.5/configure.ac Python-3.3.5-android/configure.ac ---- Python-3.3.5/configure.ac 2014-03-09 09:40:34.000000000 +0100 -+++ Python-3.3.5-android/configure.ac 2014-08-04 22:13:00.000000000 +0200 -@@ -56,13 +56,18 @@ - if test "$cross_compiling" = yes; then - AC_MSG_CHECKING([for python interpreter for cross build]) - if test -z "$PYTHON_FOR_BUILD"; then -- for interp in python$PACKAGE_VERSION python3 python; do -- which $interp >/dev/null 2>&1 || continue -- if $interp -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then -- break -- fi -- interp= -- done -+ if test ! -z "$HOSTPYTHON" && PYTHONPATH="$ac_abs_confdir/Lib" "$HOSTPYTHON" -S -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then -+ interp="$HOSTPYTHON" -+ else -+ for interp in python$PACKAGE_VERSION python3 python; do -+ which $interp >/dev/null 2>&1 || continue -+ if $interp -c 'import sys;sys.exit(not sys.version_info@<:@:2@:>@ >= (3,3))'; then -+ break -+ fi -+ interp= -+ done -+ fi -+ - if test x$interp = x; then - AC_MSG_ERROR([python$PACKAGE_VERSION interpreter not found]) - fi diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch deleted file mode 100644 index be2bde20d2..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-libpymodules_loader.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c -index 7f8f134..bba560f 100644 ---- a/Python/dynload_shlib.c -+++ b/Python/dynload_shlib.c -@@ -62,6 +62,20 @@ _PyImport_FindSharedFuncptr(const char *prefix, - char pathbuf[260]; - int dlopenflags=0; - -+ static void *libpymodules = NULL; -+ void *rv = NULL; -+ -+ /* Ensure we have access to libpymodules. */ -+ if (libpymodules == NULL) { -+ printf("ANDROID_PRIVATE = %s\n", getenv("ANDROID_PRIVATE")); -+ PyOS_snprintf(pathbuf, sizeof(pathbuf), "%s/libpymodules.so", getenv("ANDROID_PRIVATE")); -+ libpymodules = dlopen(pathbuf, RTLD_NOW); -+ -+ if (libpymodules == NULL) { -+ //abort(); -+ } -+ } -+ - if (strchr(pathname, '/') == NULL) { - /* Prefix bare filename with "./" */ - PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname); -@@ -71,6 +85,16 @@ _PyImport_FindSharedFuncptr(const char *prefix, - PyOS_snprintf(funcname, sizeof(funcname), - LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); - -+ -+ /* Read symbols that have been linked into the main binary. */ -+ -+ if (libpymodules) { -+ rv = dlsym(libpymodules, funcname); -+ if (rv != NULL) { -+ return rv; -+ } -+ } -+ - if (fp != NULL) { - int i; - struct _Py_stat_struct status; diff --git a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch b/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch deleted file mode 100644 index 5745062551..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches/python-3.4.2-python-misc.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff -ru Python-3.3.5/Lib/test/test_pwd.py Python-3.3.5-android/Lib/test/test_pwd.py ---- Python-3.3.5/Lib/test/test_pwd.py 2014-03-09 09:40:19.000000000 +0100 -+++ Python-3.3.5-android/Lib/test/test_pwd.py 2014-08-04 22:14:36.000000000 +0200 -@@ -6,6 +6,7 @@ - - class PwdTest(unittest.TestCase): - -+ @unittest.skipUnless(hasattr(pwd, 'getpwall'), 'pwd module does not expose getpwall()') - def test_values(self): - entries = pwd.getpwall() - -@@ -52,6 +53,7 @@ - self.assertIn(pwd.getpwnam(e.pw_name), entriesbyname[e.pw_name]) - self.assertIn(pwd.getpwuid(e.pw_uid), entriesbyuid[e.pw_uid]) - -+ @unittest.skipUnless(hasattr(pwd, 'getpwall'), 'pwd module does not expose getpwall()') - def test_errors(self): - self.assertRaises(TypeError, pwd.getpwuid) - self.assertRaises(TypeError, pwd.getpwuid, 3.14) -diff -ru Python-3.4.2/Modules/python.c Python-3.4.2-android/Modules/python.c ---- Python-3.4.2/Modules/python.c 2015-02-24 22:42:37.000000000 +0100 -+++ Python-3.4.2-android/Modules/python.c 2015-02-24 23:04:27.000000000 +0100 -@@ -44,10 +44,13 @@ - fpsetmask(m & ~FP_X_OFL); - #endif - -- oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); -- if (!oldloc) { -- fprintf(stderr, "out of memory\n"); -- return 1; -+ oldloc = setlocale(LC_ALL, NULL); -+ if (oldloc) { -+ oldloc = _PyMem_RawStrdup(oldloc); -+ if (!oldloc) { -+ fprintf(stderr, "out of memory\n"); -+ return 1; -+ } - } - - setlocale(LC_ALL, ""); -@@ -64,8 +67,11 @@ - } - argv_copy2[argc] = argv_copy[argc] = NULL; - -- setlocale(LC_ALL, oldloc); -- PyMem_RawFree(oldloc); -+ if (oldloc) { -+ setlocale(LC_ALL, oldloc); -+ PyMem_RawFree(oldloc); -+ } -+ - res = Py_Main(argc, argv_copy); - for (i = 0; i < argc; i++) { - PyMem_RawFree(argv_copy2[i]); -diff -ru Python-3.3.5/setup.py Python-3.3.5-android/setup.py ---- Python-3.3.5/setup.py 2014-03-09 09:40:35.000000000 +0100 -+++ Python-3.3.5-android/setup.py 2014-08-04 22:14:36.000000000 +0200 -@@ -562,7 +562,7 @@ - libraries=math_libs) ) - - # time libraries: librt may be needed for clock_gettime() -- time_libs = [] -+ time_libs = ['m'] - lib = sysconfig.get_config_var('TIMEMODULE_LIB') - if lib: - time_libs.append(lib) -@@ -639,7 +639,8 @@ - # Operations on audio samples - # According to #993173, this one should actually work fine on - # 64-bit platforms. -- exts.append( Extension('audioop', ['audioop.c']) ) -+ exts.append( Extension('audioop', ['audioop.c'], -+ libraries=['m']) ) - - # readline - do_readline = self.compiler.find_library_file(lib_dirs, 'readline') -@@ -1904,7 +1905,8 @@ - sources=sources, - depends=depends) - ext_test = Extension('_ctypes_test', -- sources=['_ctypes/_ctypes_test.c']) -+ sources=['_ctypes/_ctypes_test.c'], -+ libraries=['m']) - self.extensions.extend([ext, ext_test]) - - if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"): diff --git a/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch b/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch deleted file mode 100644 index d51684e5d6..0000000000 --- a/pythonforandroid/recipes/python3crystax/patches_inclement/python-3.5.0-android-locale.patch +++ /dev/null @@ -1,573 +0,0 @@ -diff --git a/Lib/platform.py b/Lib/platform.py -index 9096696..66a6455 100755 ---- a/Lib/platform.py -+++ b/Lib/platform.py -@@ -382,6 +382,64 @@ def dist(distname='', version='', id='', - supported_dists=supported_dists, - full_distribution_name=0) - -+_android_environment_vars = ( -+ 'ANDROID_ROOT', 'ANDROID_ASSETS', 'ANDROID_STORAGE', 'ANDROID_DATA', -+ 'ANDROID_PROPERTY_WORKSPACE', 'ANDROID_BOOTLOGO') -+_android_version_property = 'ro.build.version.release' -+_android_buildstr_property = 'ro.build.version.full' -+ -+def android_version(version='', buildstr=''): -+ """ Attempt to get the Android version number and build string. -+ -+ The function checks for the getprop binary to retrieve build info, -+ and falls back to manually reading /system/build.prop if available. -+ -+ Returns a (version, buildstr) tuple which defaults to the args given -+ as parameters. -+ """ -+ if not any(os.getenv(e) for e in _android_environment_vars): -+ # Probably not on Android... -+ return version, buildstr -+ -+ version_obtained = False -+ buildstr_obtained = False -+ -+ # Try the 'official' API tool first, since /system/build.prop might -+ # not be the only source for properties. -+ if os.access('/system/bin/getprop', os.X_OK): -+ try: -+ output = subprocess.check_output(['/system/bin/getprop', -+ _android_version_property]) -+ version = output.decode('ascii').strip() -+ version_obtained = True -+ except (subprocess.CalledProcessError, UnicodeDecodeError): -+ pass -+ -+ try: -+ output = subprocess.check_output(['/system/bin/getprop', -+ _android_buildstr_property]) -+ buildstr = output.decode('ascii').strip() -+ buildstr_obtained = True -+ except (subprocess.CalledProcessError, UnicodeDecodeError): -+ pass -+ done = version_obtained and buildstr_obtained -+ -+ # Fall back to parsing /system/build.prop manually. -+ if not done and os.path.isfile('/system/build.prop'): -+ for line in open('/system/build.prop'): -+ if '=' not in line: -+ continue -+ key, val = line.split('=') -+ key = key.strip() -+ -+ if not version_obtained and key == _android_version_property: -+ version = val.strip() -+ elif not buildstr_obtained and key == _android_buildstr_property: -+ buildstr = val.strip() -+ -+ return version, buildstr -+ -+ - def popen(cmd, mode='r', bufsize=-1): - - """ Portable popen() interface. -diff --git a/Lib/subprocess.py b/Lib/subprocess.py -index b6c4374..51dec9c 100644 ---- a/Lib/subprocess.py -+++ b/Lib/subprocess.py -@@ -1429,9 +1429,18 @@ class Popen(object): - args = list(args) - - if shell: -- args = ["/bin/sh", "-c"] + args - if executable: -- args[0] = executable -+ main = executable -+ elif os.path.isfile('/bin/sh'): -+ main = '/bin/sh' -+ else: -+ import platform -+ if platform.android_version()[0]: -+ main = '/system/bin/sh' -+ else: -+ raise RuntimeError('Could not find system shell') -+ -+ args = [main, "-c"] + args - - if executable is None: - executable = args[0] -diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py -index 9c0229a..d711647 100644 ---- a/Lib/test/test_subprocess.py -+++ b/Lib/test/test_subprocess.py -@@ -18,6 +18,7 @@ import select - import shutil - import gc - import textwrap -+import platform - - try: - import threading -@@ -1530,8 +1531,11 @@ class POSIXProcessTestCase(BaseTestCase): - fd, fname = mkstemp() - # reopen in text mode - with open(fd, "w", errors="surrogateescape") as fobj: -- fobj.write("#!/bin/sh\n") -- fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % -+ if platform.android_version()[0]: -+ fobj.write('#!/system/bin/sh\n') -+ else: -+ fobj.write("#!/bin/sh\n") -+ fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.chmod(fname, 0o700) - p = subprocess.Popen(fname) -@@ -1575,7 +1579,10 @@ class POSIXProcessTestCase(BaseTestCase): - fd, fname = mkstemp() - # reopen in text mode - with open(fd, "w", errors="surrogateescape") as fobj: -- fobj.write("#!/bin/sh\n") -+ if platform.android_version()[0]: -+ fobj.write('#!/system/bin/sh\n') -+ else: -+ fobj.write("#!/bin/sh\n") - fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.chmod(fname, 0o700) -diff --git a/Makefile.pre.in b/Makefile.pre.in -index ce2c0aa..cc401eb 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -580,7 +580,7 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED) -lpython$(LDVERSION)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - -@@ -597,11 +597,9 @@ $(LIBRARY): $(LIBRARY_OBJS) - $(RANLIB) $@ - - libpython$(LDVERSION).so: $(LIBRARY_OBJS) -+ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - if test $(INSTSONAME) != $(LDLIBRARY); then \ -- $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - $(LN) -f $(INSTSONAME) $@; \ -- else \ -- $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - fi - - libpython3.so: libpython$(LDVERSION).so -diff --git a/Modules/Setup.dist b/Modules/Setup.dist -index 06ba6ad..3c5115c 100644 ---- a/Modules/Setup.dist -+++ b/Modules/Setup.dist -@@ -121,7 +121,7 @@ _stat _stat.c # stat.h interface - time timemodule.c # -lm # time operations and variables - - # access to ISO C locale support --_locale _localemodule.c # -lintl -+#_locale _localemodule.c # -lintl - - # Standard I/O baseline - _io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c -diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c -index a45a429..e87101d 100644 ---- a/Modules/_decimal/libmpdec/io.c -+++ b/Modules/_decimal/libmpdec/io.c -@@ -868,10 +868,16 @@ mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps) - } - spec->type = *cp++; - spec->type = (spec->type == 'N') ? 'G' : 'g'; -+#ifdef __ANDROID__ -+ spec->dot = "."; -+ spec->sep = ","; -+ spec->grouping = "\3"; -+#else - lc = localeconv(); - spec->dot = lc->decimal_point; - spec->sep = lc->thousands_sep; - spec->grouping = lc->grouping; -+#endif - if (mpd_validate_lconv(spec) < 0) { - return 0; /* GCOV_NOT_REACHED */ - } -diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c -index b1d6add..2c6ec0e 100644 ---- a/Modules/_localemodule.c -+++ b/Modules/_localemodule.c -@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. - #include - #endif - -+#if __ANDROID__ -+/* Android's locale support is pretty much unusable, it's better to have the -+ higher-level module fall back to C locale emulation. */ -+#error "Android's locale support is too incomplete to create a usable module." -+#endif -+ -+ - PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); - - static PyObject *Error; -@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) - if (!result) - return NULL; - -+#ifdef __ANDROID__ -+ /* Don't even try on Android's broken locale.h. */ -+ goto failed; -+#else -+ - /* if LC_NUMERIC is different in the C library, use saved value */ - l = localeconv(); - -@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) - RESULT_INT(n_sign_posn); - return result; - -+#endif // __ANDROID__ -+ - failed: - Py_XDECREF(result); - return NULL; -diff --git a/Modules/main.c b/Modules/main.c -index 2a9ea28..e32f305 100644 ---- a/Modules/main.c -+++ b/Modules/main.c -@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) - oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - /* Use utf-8 on Mac OS X */ - unicode = PyUnicode_FromString(p); - #else -diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c -index ec8c526..08e8021 100644 ---- a/Modules/posixmodule.c -+++ b/Modules/posixmodule.c -@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); - PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, - ULONG, struct _Py_stat_struct *); - #endif -+ -+/* Android doesn't expose AT_EACCESS - manually define it. */ -+#if !defined(AT_EACCESS) && defined(__ANDROID__) -+#define AT_EACCESS 0x200 -+#endif - - #ifdef MS_WINDOWS - static int -diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c -index 281c30b..28b93c2 100644 ---- a/Modules/pwdmodule.c -+++ b/Modules/pwdmodule.c -@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) - SETS(setIndex++, p->pw_passwd); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -+#if !defined(__ANDROID__) - SETS(setIndex++, p->pw_gecos); -+#else -+ SETS(setIndex++, ""); -+#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - -diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c -index ee24907..3718f70 100644 ---- a/Modules/socketmodule.c -+++ b/Modules/socketmodule.c -@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - --#ifndef linux -+#if !defined(linux) || __ANDROID__ - # undef HAVE_GETHOSTBYNAME_R_3_ARG - # undef HAVE_GETHOSTBYNAME_R_5_ARG - # undef HAVE_GETHOSTBYNAME_R_6_ARG -@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - # define HAVE_GETHOSTBYNAME_R_3_ARG - # elif defined(__sun) || defined(__sgi) - # define HAVE_GETHOSTBYNAME_R_5_ARG --# elif defined(linux) -+# elif defined(linux) && !__ANDROID__ - /* Rely on the configure script */ - # else - # undef HAVE_GETHOSTBYNAME_R -diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c -index 9223c99..1f8f625 100644 ---- a/Objects/unicodeobject.c -+++ b/Objects/unicodeobject.c -@@ -3163,12 +3163,20 @@ static int - locale_error_handler(const char *errors, int *surrogateescape) - { - if (errors == NULL) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - - if (strcmp(errors, "strict") == 0) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - if (strcmp(errors, "surrogateescape") == 0) { -@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) - { - #ifdef HAVE_MBCS - return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) - { - #ifdef HAVE_MBCS - return PyUnicode_DecodeMBCS(s, size, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -4769,7 +4777,7 @@ onError: - return NULL; - } - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - - /* Simplified UTF-8 decoder using surrogateescape error handler, - used to decode the command line arguments on Mac OS X. -diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c -index 2f22209..ba42d84 100644 ---- a/Python/bltinmodule.c -+++ b/Python/bltinmodule.c -@@ -24,7 +24,7 @@ - #ifdef HAVE_MBCS - const char *Py_FileSystemDefaultEncoding = "mbcs"; - int Py_HasFileSystemDefaultEncoding = 1; --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - const char *Py_FileSystemDefaultEncoding = "utf-8"; - int Py_HasFileSystemDefaultEncoding = 1; - #else -diff --git a/Python/fileutils.c b/Python/fileutils.c -index bccd321..48ae1a5 100644 ---- a/Python/fileutils.c -+++ b/Python/fileutils.c -@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); - #include - #endif /* HAVE_FCNTL_H */ - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); - #endif - -@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) - Py_RETURN_NONE; - } - --#if !defined(__APPLE__) && !defined(MS_WINDOWS) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) - extern int _Py_normalize_encoding(const char *, char *, size_t); - - /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. -@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) - } - #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ - --#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) - static wchar_t* - decode_ascii_surrogateescape(const char *arg, size_t *size) - { -@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) - wchar_t* - Py_DecodeLocale(const char* arg, size_t *size) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - wchar_t *wstr; - wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); - if (size != NULL) { -@@ -423,7 +423,7 @@ oom: - char* - Py_EncodeLocale(const wchar_t *text, size_t *error_pos) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - Py_ssize_t len; - PyObject *unicode, *bytes = NULL; - char *cpath; -diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c -index 056bb76..c9d761e 100644 ---- a/Python/formatter_unicode.c -+++ b/Python/formatter_unicode.c -@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - { - switch (type) { - case LT_CURRENT_LOCALE: { -+#ifndef __ANDROID__ - struct lconv *locale_data = localeconv(); - locale_info->decimal_point = PyUnicode_DecodeLocale( - locale_data->decimal_point, -@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - } - locale_info->grouping = locale_data->grouping; - break; -+#endif // __ANDROID__ - } - case LT_DEFAULT_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); -diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c -index a17adf7..0843158 100644 ---- a/Python/pylifecycle.c -+++ b/Python/pylifecycle.c -@@ -224,6 +224,8 @@ get_locale_encoding(void) - return NULL; - } - return get_codec_name(codeset); -+#elif __ANDROID__ -+ return get_codec_name("UTF-8"); - #else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -diff --git a/Python/pystrtod.c b/Python/pystrtod.c -index 209c908..6bd792a 100644 ---- a/Python/pystrtod.c -+++ b/Python/pystrtod.c -@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) - - fail_pos = NULL; - -+#ifdef __ANDROID__ -+ decimal_point = "."; -+#else - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; -+#endif - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); -@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, - Py_LOCAL_INLINE(void) - change_decimal_from_locale_to_dot(char* buffer) - { -+#ifdef __ANDROID__ -+ const char *decimal_point = "."; -+#else - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; -+#endif - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); -diff --git a/configure b/configure -index e823a08..dc7c760 100755 ---- a/configure -+++ b/configure -@@ -5065,6 +5065,35 @@ fi - - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - -+# Test if we're running on Android. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 -+$as_echo_n "checking if target is Android-based... " >&6; } -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+#if __ANDROID__ -+yes -+#endif -+ -+_ACEOF -+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -+ $EGREP "yes" >/dev/null 2>&1; then : -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ with_android=yes -+ -+else -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ with_android=no -+ -+ -+fi -+rm -f conftest* -+ -+ - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 - $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } -@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} -- INSTSONAME="$LDLIBRARY".$SOVERSION -+ if test "$with_android" != yes -+ then -+ INSTSONAME="$LDLIBRARY".$SOVERSION -+ else -+ INSTSONAME="LDLIBRARY" -+ fi -+ - if test "$with_pydebug" != yes - then - PY3LIBRARY=libpython3.so -diff --git a/configure.ac b/configure.ac -index 56a73df..3245d87 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -726,6 +726,22 @@ fi - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - AC_SUBST(MULTIARCH) - -+# Test if we're running on Android. -+AC_MSG_CHECKING(if target is Android-based) -+AC_EGREP_CPP(yes, -+[ -+#if __ANDROID__ -+yes -+#endif -+], [ -+ AC_MSG_RESULT(yes) -+ with_android=yes -+ ], [ -+ AC_MSG_RESULT(no) -+ with_android=no -+ ] -+) -+ - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) - cat >> conftest.c <type = *cp++; - spec->type = (spec->type == 'N') ? 'G' : 'g'; -+#ifdef __ANDROID__ -+ spec->dot = "."; -+ spec->sep = ","; -+ spec->grouping = "\3"; -+#else - lc = localeconv(); - spec->dot = lc->decimal_point; - spec->sep = lc->thousands_sep; - spec->grouping = lc->grouping; -+#endif - if (mpd_validate_lconv(spec) < 0) { - return 0; /* GCOV_NOT_REACHED */ - } -diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c -index b1d6add..2c6ec0e 100644 ---- a/Modules/_localemodule.c -+++ b/Modules/_localemodule.c -@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. - #include - #endif - -+#if __ANDROID__ -+/* Android's locale support is pretty much unusable, it's better to have the -+ higher-level module fall back to C locale emulation. */ -+#error "Android's locale support is too incomplete to create a usable module." -+#endif -+ -+ - PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); - - static PyObject *Error; -@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) - if (!result) - return NULL; - -+#ifdef __ANDROID__ -+ /* Don't even try on Android's broken locale.h. */ -+ goto failed; -+#else -+ - /* if LC_NUMERIC is different in the C library, use saved value */ - l = localeconv(); - -@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) - RESULT_INT(n_sign_posn); - return result; - -+#endif // __ANDROID__ -+ - failed: - Py_XDECREF(result); - return NULL; -diff --git a/Modules/main.c b/Modules/main.c -index 2a9ea28..e32f305 100644 ---- a/Modules/main.c -+++ b/Modules/main.c -@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) - oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - /* Use utf-8 on Mac OS X */ - unicode = PyUnicode_FromString(p); - #else -diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c -index ec8c526..08e8021 100644 ---- a/Modules/posixmodule.c -+++ b/Modules/posixmodule.c -@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); - PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, - ULONG, struct _Py_stat_struct *); - #endif -+ -+/* Android doesn't expose AT_EACCESS - manually define it. */ -+#if !defined(AT_EACCESS) && defined(__ANDROID__) -+#define AT_EACCESS 0x200 -+#endif - - #ifdef MS_WINDOWS - static int -diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c -index 281c30b..28b93c2 100644 ---- a/Modules/pwdmodule.c -+++ b/Modules/pwdmodule.c -@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) - SETS(setIndex++, p->pw_passwd); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -+#if !defined(__ANDROID__) - SETS(setIndex++, p->pw_gecos); -+#else -+ SETS(setIndex++, ""); -+#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - -diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c -index ee24907..3718f70 100644 ---- a/Modules/socketmodule.c -+++ b/Modules/socketmodule.c -@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - --#ifndef linux -+#if !defined(linux) || __ANDROID__ - # undef HAVE_GETHOSTBYNAME_R_3_ARG - # undef HAVE_GETHOSTBYNAME_R_5_ARG - # undef HAVE_GETHOSTBYNAME_R_6_ARG -@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - # define HAVE_GETHOSTBYNAME_R_3_ARG - # elif defined(__sun) || defined(__sgi) - # define HAVE_GETHOSTBYNAME_R_5_ARG --# elif defined(linux) -+# elif defined(linux) && !__ANDROID__ - /* Rely on the configure script */ - # else - # undef HAVE_GETHOSTBYNAME_R -diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c -index 9223c99..1f8f625 100644 ---- a/Objects/unicodeobject.c -+++ b/Objects/unicodeobject.c -@@ -3163,12 +3163,20 @@ static int - locale_error_handler(const char *errors, int *surrogateescape) - { - if (errors == NULL) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - - if (strcmp(errors, "strict") == 0) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - if (strcmp(errors, "surrogateescape") == 0) { -@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) - { - #ifdef HAVE_MBCS - return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) - { - #ifdef HAVE_MBCS - return PyUnicode_DecodeMBCS(s, size, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -4769,7 +4777,7 @@ onError: - return NULL; - } - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - - /* Simplified UTF-8 decoder using surrogateescape error handler, - used to decode the command line arguments on Mac OS X. -diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c -index 2f22209..ba42d84 100644 ---- a/Python/bltinmodule.c -+++ b/Python/bltinmodule.c -@@ -24,7 +24,7 @@ - #ifdef HAVE_MBCS - const char *Py_FileSystemDefaultEncoding = "mbcs"; - int Py_HasFileSystemDefaultEncoding = 1; --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - const char *Py_FileSystemDefaultEncoding = "utf-8"; - int Py_HasFileSystemDefaultEncoding = 1; - #else -diff --git a/Python/fileutils.c b/Python/fileutils.c -index bccd321..48ae1a5 100644 ---- a/Python/fileutils.c -+++ b/Python/fileutils.c -@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); - #include - #endif /* HAVE_FCNTL_H */ - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); - #endif - -@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) - Py_RETURN_NONE; - } - --#if !defined(__APPLE__) && !defined(MS_WINDOWS) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) - extern int _Py_normalize_encoding(const char *, char *, size_t); - - /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. -@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) - } - #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ - --#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) - static wchar_t* - decode_ascii_surrogateescape(const char *arg, size_t *size) - { -@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) - wchar_t* - Py_DecodeLocale(const char* arg, size_t *size) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - wchar_t *wstr; - wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); - if (size != NULL) { -@@ -423,7 +423,7 @@ oom: - char* - Py_EncodeLocale(const wchar_t *text, size_t *error_pos) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - Py_ssize_t len; - PyObject *unicode, *bytes = NULL; - char *cpath; -diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c -index 056bb76..c9d761e 100644 ---- a/Python/formatter_unicode.c -+++ b/Python/formatter_unicode.c -@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - { - switch (type) { - case LT_CURRENT_LOCALE: { -+#ifndef __ANDROID__ - struct lconv *locale_data = localeconv(); - locale_info->decimal_point = PyUnicode_DecodeLocale( - locale_data->decimal_point, -@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - } - locale_info->grouping = locale_data->grouping; - break; -+#endif // __ANDROID__ - } - case LT_DEFAULT_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); -diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c -index a17adf7..0843158 100644 ---- a/Python/pylifecycle.c -+++ b/Python/pylifecycle.c -@@ -224,6 +224,8 @@ get_locale_encoding(void) - return NULL; - } - return get_codec_name(codeset); -+#elif __ANDROID__ -+ return get_codec_name("UTF-8"); - #else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -diff --git a/Python/pystrtod.c b/Python/pystrtod.c -index 209c908..6bd792a 100644 ---- a/Python/pystrtod.c -+++ b/Python/pystrtod.c -@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) - - fail_pos = NULL; - -+#ifdef __ANDROID__ -+ decimal_point = "."; -+#else - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; -+#endif - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); -@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, - Py_LOCAL_INLINE(void) - change_decimal_from_locale_to_dot(char* buffer) - { -+#ifdef __ANDROID__ -+ const char *decimal_point = "."; -+#else - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; -+#endif - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); -diff --git a/configure b/configure -index e823a08..dc7c760 100755 ---- a/configure -+++ b/configure -@@ -5065,6 +5065,35 @@ fi - - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - -+# Test if we're running on Android. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 -+$as_echo_n "checking if target is Android-based... " >&6; } -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+#if __ANDROID__ -+yes -+#endif -+ -+_ACEOF -+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -+ $EGREP "yes" >/dev/null 2>&1; then : -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ with_android=yes -+ -+else -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ with_android=no -+ -+ -+fi -+rm -f conftest* -+ -+ - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 - $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } -@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} -- INSTSONAME="$LDLIBRARY".$SOVERSION -+ if test "$with_android" != yes -+ then -+ INSTSONAME="$LDLIBRARY".$SOVERSION -+ else -+ INSTSONAME="LDLIBRARY" -+ fi -+ - if test "$with_pydebug" != yes - then - PY3LIBRARY=libpython3.so -diff --git a/configure.ac b/configure.ac -index 56a73df..3245d87 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -726,6 +726,22 @@ fi - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - AC_SUBST(MULTIARCH) - -+# Test if we're running on Android. -+AC_MSG_CHECKING(if target is Android-based) -+AC_EGREP_CPP(yes, -+[ -+#if __ANDROID__ -+yes -+#endif -+], [ -+ AC_MSG_RESULT(yes) -+ with_android=yes -+ ], [ -+ AC_MSG_RESULT(no) -+ with_android=no -+ ] -+) -+ - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) - cat >> conftest.c <type = *cp++; - spec->type = (spec->type == 'N') ? 'G' : 'g'; -+#ifdef __ANDROID__ -+ spec->dot = "."; -+ spec->sep = ","; -+ spec->grouping = "\3"; -+#else - lc = localeconv(); - spec->dot = lc->decimal_point; - spec->sep = lc->thousands_sep; - spec->grouping = lc->grouping; -+#endif - if (mpd_validate_lconv(spec) < 0) { - return 0; /* GCOV_NOT_REACHED */ - } -diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c -index b1d6add..2c6ec0e 100644 ---- a/Modules/_localemodule.c -+++ b/Modules/_localemodule.c -@@ -38,6 +38,13 @@ This software comes with no warranty. Use at your own risk. - #include - #endif - -+#if __ANDROID__ -+/* Android's locale support is pretty much unusable, it's better to have the -+ higher-level module fall back to C locale emulation. */ -+#error "Android's locale support is too incomplete to create a usable module." -+#endif -+ -+ - PyDoc_STRVAR(locale__doc__, "Support for POSIX locales."); - - static PyObject *Error; -@@ -141,6 +148,11 @@ PyLocale_localeconv(PyObject* self) - if (!result) - return NULL; - -+#ifdef __ANDROID__ -+ /* Don't even try on Android's broken locale.h. */ -+ goto failed; -+#else -+ - /* if LC_NUMERIC is different in the C library, use saved value */ - l = localeconv(); - -@@ -196,6 +208,8 @@ PyLocale_localeconv(PyObject* self) - RESULT_INT(n_sign_posn); - return result; - -+#endif // __ANDROID__ -+ - failed: - Py_XDECREF(result); - return NULL; -diff --git a/Modules/main.c b/Modules/main.c -index 2a9ea28..e32f305 100644 ---- a/Modules/main.c -+++ b/Modules/main.c -@@ -549,7 +549,7 @@ Py_Main(int argc, wchar_t **argv) - oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - /* Use utf-8 on Mac OS X */ - unicode = PyUnicode_FromString(p); - #else -diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c -index ec8c526..08e8021 100644 ---- a/Modules/posixmodule.c -+++ b/Modules/posixmodule.c -@@ -387,6 +387,11 @@ PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); - PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, - ULONG, struct _Py_stat_struct *); - #endif -+ -+/* Android doesn't expose AT_EACCESS - manually define it. */ -+#if !defined(AT_EACCESS) && defined(__ANDROID__) -+#define AT_EACCESS 0x200 -+#endif - - #ifdef MS_WINDOWS - static int -diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c -index 281c30b..28b93c2 100644 ---- a/Modules/pwdmodule.c -+++ b/Modules/pwdmodule.c -@@ -78,7 +78,11 @@ mkpwent(struct passwd *p) - SETS(setIndex++, p->pw_passwd); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -+#if !defined(__ANDROID__) - SETS(setIndex++, p->pw_gecos); -+#else -+ SETS(setIndex++, ""); -+#endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); - -diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c -index ee24907..3718f70 100644 ---- a/Modules/socketmodule.c -+++ b/Modules/socketmodule.c -@@ -148,7 +148,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - On the other hand, not all Linux versions agree, so there the settings - computed by the configure script are needed! */ - --#ifndef linux -+#if !defined(linux) || __ANDROID__ - # undef HAVE_GETHOSTBYNAME_R_3_ARG - # undef HAVE_GETHOSTBYNAME_R_5_ARG - # undef HAVE_GETHOSTBYNAME_R_6_ARG -@@ -167,7 +167,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ - # define HAVE_GETHOSTBYNAME_R_3_ARG - # elif defined(__sun) || defined(__sgi) - # define HAVE_GETHOSTBYNAME_R_5_ARG --# elif defined(linux) -+# elif defined(linux) && !__ANDROID__ - /* Rely on the configure script */ - # else - # undef HAVE_GETHOSTBYNAME_R -diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c -index 9223c99..1f8f625 100644 ---- a/Objects/unicodeobject.c -+++ b/Objects/unicodeobject.c -@@ -3163,12 +3163,20 @@ static int - locale_error_handler(const char *errors, int *surrogateescape) - { - if (errors == NULL) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - - if (strcmp(errors, "strict") == 0) { -+#ifdef __ANDROID__ -+ *surrogateescape = 1; -+#else - *surrogateescape = 0; -+#endif - return 0; - } - if (strcmp(errors, "surrogateescape") == 0) { -@@ -3297,7 +3305,7 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) - { - #ifdef HAVE_MBCS - return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return _PyUnicode_AsUTF8String(unicode, "surrogateescape"); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -3581,7 +3589,7 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) - { - #ifdef HAVE_MBCS - return PyUnicode_DecodeMBCS(s, size, NULL); --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - return PyUnicode_DecodeUTF8Stateful(s, size, "surrogateescape", NULL); - #else - PyInterpreterState *interp = PyThreadState_GET()->interp; -@@ -4769,7 +4777,7 @@ onError: - return NULL; - } - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - - /* Simplified UTF-8 decoder using surrogateescape error handler, - used to decode the command line arguments on Mac OS X. -diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c -index 2f22209..ba42d84 100644 ---- a/Python/bltinmodule.c -+++ b/Python/bltinmodule.c -@@ -24,7 +24,7 @@ - #ifdef HAVE_MBCS - const char *Py_FileSystemDefaultEncoding = "mbcs"; - int Py_HasFileSystemDefaultEncoding = 1; --#elif defined(__APPLE__) -+#elif defined(__APPLE__) || defined(__ANDROID__) - const char *Py_FileSystemDefaultEncoding = "utf-8"; - int Py_HasFileSystemDefaultEncoding = 1; - #else -diff --git a/Python/fileutils.c b/Python/fileutils.c -index bccd321..48ae1a5 100644 ---- a/Python/fileutils.c -+++ b/Python/fileutils.c -@@ -20,7 +20,7 @@ extern int winerror_to_errno(int); - #include - #endif /* HAVE_FCNTL_H */ - --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); - #endif - -@@ -70,7 +70,7 @@ _Py_device_encoding(int fd) - Py_RETURN_NONE; - } - --#if !defined(__APPLE__) && !defined(MS_WINDOWS) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(MS_WINDOWS) - extern int _Py_normalize_encoding(const char *, char *, size_t); - - /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale. -@@ -220,7 +220,7 @@ encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos) - } - #endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */ - --#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) -+#if !defined(__APPLE__) && !defined(__ANDROID__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC)) - static wchar_t* - decode_ascii_surrogateescape(const char *arg, size_t *size) - { -@@ -272,7 +272,7 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) - wchar_t* - Py_DecodeLocale(const char* arg, size_t *size) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - wchar_t *wstr; - wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg)); - if (size != NULL) { -@@ -423,7 +423,7 @@ oom: - char* - Py_EncodeLocale(const wchar_t *text, size_t *error_pos) - { --#ifdef __APPLE__ -+#if defined(__APPLE__) || defined(__ANDROID__) - Py_ssize_t len; - PyObject *unicode, *bytes = NULL; - char *cpath; -diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c -index 056bb76..c9d761e 100644 ---- a/Python/formatter_unicode.c -+++ b/Python/formatter_unicode.c -@@ -667,6 +667,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - { - switch (type) { - case LT_CURRENT_LOCALE: { -+#ifndef __ANDROID__ - struct lconv *locale_data = localeconv(); - locale_info->decimal_point = PyUnicode_DecodeLocale( - locale_data->decimal_point, -@@ -682,6 +683,7 @@ get_locale_info(int type, LocaleInfo *locale_info) - } - locale_info->grouping = locale_data->grouping; - break; -+#endif // __ANDROID__ - } - case LT_DEFAULT_LOCALE: - locale_info->decimal_point = PyUnicode_FromOrdinal('.'); -diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c -index a17adf7..0843158 100644 ---- a/Python/pylifecycle.c -+++ b/Python/pylifecycle.c -@@ -224,6 +224,8 @@ get_locale_encoding(void) - return NULL; - } - return get_codec_name(codeset); -+#elif __ANDROID__ -+ return get_codec_name("UTF-8"); - #else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -diff --git a/Python/pystrtod.c b/Python/pystrtod.c -index 209c908..6bd792a 100644 ---- a/Python/pystrtod.c -+++ b/Python/pystrtod.c -@@ -177,8 +177,12 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) - - fail_pos = NULL; - -+#ifdef __ANDROID__ -+ decimal_point = "."; -+#else - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; -+#endif - decimal_point_len = strlen(decimal_point); - - assert(decimal_point_len != 0); -@@ -378,8 +382,12 @@ PyOS_string_to_double(const char *s, - Py_LOCAL_INLINE(void) - change_decimal_from_locale_to_dot(char* buffer) - { -+#ifdef __ANDROID__ -+ const char *decimal_point = "."; -+#else - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; -+#endif - - if (decimal_point[0] != '.' || decimal_point[1] != 0) { - size_t decimal_point_len = strlen(decimal_point); -diff --git a/configure b/configure -index e823a08..dc7c760 100755 ---- a/configure -+++ b/configure -@@ -5065,6 +5065,35 @@ fi - - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - -+# Test if we're running on Android. -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target is Android-based" >&5 -+$as_echo_n "checking if target is Android-based... " >&6; } -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+/* end confdefs.h. */ -+ -+#if __ANDROID__ -+yes -+#endif -+ -+_ACEOF -+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -+ $EGREP "yes" >/dev/null 2>&1; then : -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -+$as_echo "yes" >&6; } -+ with_android=yes -+ -+else -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ with_android=no -+ -+ -+fi -+rm -f conftest* -+ -+ - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 - $as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } -@@ -5791,7 +5820,13 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h - LDLIBRARY='libpython$(LDVERSION).so' - BLDLIBRARY='-L. -lpython$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} -- INSTSONAME="$LDLIBRARY".$SOVERSION -+ if test "$with_android" != yes -+ then -+ INSTSONAME="$LDLIBRARY".$SOVERSION -+ else -+ INSTSONAME="LDLIBRARY" -+ fi -+ - if test "$with_pydebug" != yes - then - PY3LIBRARY=libpython3.so -diff --git a/configure.ac b/configure.ac -index 56a73df..3245d87 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -726,6 +726,22 @@ fi - MULTIARCH=$($CC --print-multiarch 2>/dev/null) - AC_SUBST(MULTIARCH) - -+# Test if we're running on Android. -+AC_MSG_CHECKING(if target is Android-based) -+AC_EGREP_CPP(yes, -+[ -+#if __ANDROID__ -+yes -+#endif -+], [ -+ AC_MSG_RESULT(yes) -+ with_android=yes -+ ], [ -+ AC_MSG_RESULT(no) -+ with_android=no -+ ] -+) -+ - AC_MSG_CHECKING([for the platform triplet based on compiler characteristics]) - cat >> conftest.c < Date: Thu, 24 Dec 2015 14:47:51 +0000 Subject: [PATCH 08/43] Changed python3crystax install process --- pythonforandroid/build.py | 7 ---- pythonforandroid/recipe.py | 25 +++++++------- .../recipes/python3crystax/__init__.py | 33 ++++++++++++++----- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py index a146401e42..05c16d931f 100644 --- a/pythonforandroid/build.py +++ b/pythonforandroid/build.py @@ -130,13 +130,6 @@ def ndk_ver(self, value): def ndk_is_crystax(self): return True if self.ndk_ver[:7] == 'crystax' else False - def ensure_crystax_python_install_dir(self): - dirn = self.get_python_install_dir() - ensure_dir(dirn) - ensure_dir(join(dirn, 'lib')) - sh.cp('-r', '/home/asandy/kivytest/crystax_stdlib', join(dirn, 'lib', 'python3.5')) - sh.cp('-r', '/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/libs/armeabi/modules', join(dirn, 'lib', 'python3.5', 'lib-dynload')) - ensure_dir(join(dirn, 'lib', 'site-packages')) @property def sdk_dir(self): diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index e29bff0fbf..c88a13e8df 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -719,25 +719,26 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True): if self.ctx.ndk_is_crystax: - hppath = join(dirname(self.hostpython_location), 'Lib', - 'site-packages') + # hppath = join(dirname(self.hostpython_location), 'Lib', + # 'site-packages') hpenv = env.copy() - if 'PYTHONPATH' in hpenv: - hpenv['PYTHONPATH'] = ':'.join([hppath] + - hpenv['PYTHONPATH'].split(':')) - else: - hpenv['PYTHONPATH'] = hppath + # if 'PYTHONPATH' in hpenv: + # hpenv['PYTHONPATH'] = ':'.join([hppath] + + # hpenv['PYTHONPATH'].split(':')) + # else: + # hpenv['PYTHONPATH'] = hppath # hpenv['PYTHONHOME'] = self.ctx.get_python_install_dir() # shprint(hostpython, 'setup.py', 'build', # _env=hpenv, *self.setup_extra_args) shprint(hostpython, 'setup.py', 'install', '-O2', '--root={}'.format(self.ctx.get_python_install_dir()), - '--install-lib=lib/python3.5/site-packages', + '--install-lib=.', + # AND: will need to unhardcode the 3.5 when adding 2.7 (and other crystax supported versions) _env=hpenv, *self.setup_extra_args) - site_packages_dir = self.ctx.get_site_packages_dir() - built_files = glob.glob(join('build', 'lib*', '*')) - for filen in built_files: - shprint(sh.cp, '-r', filen, join(site_packages_dir, split(filen)[-1])) + # site_packages_dir = self.ctx.get_site_packages_dir() + # built_files = glob.glob(join('build', 'lib*', '*')) + # for filen in built_files: + # shprint(sh.cp, '-r', filen, join(site_packages_dir, split(filen)[-1])) elif self.call_hostpython_via_targetpython: shprint(hostpython, 'setup.py', 'install', '-O2', _env=env, *self.setup_extra_args) diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py index 7b7b7bdd92..e1e35997ca 100644 --- a/pythonforandroid/recipes/python3crystax/__init__.py +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -1,28 +1,45 @@ from pythonforandroid.toolchain import Recipe, shprint, current_directory, ArchARM from pythonforandroid.logger import info +from pythonforandroid.util import ensure_dir from os.path import exists, join from os import uname import glob import sh class Python3Recipe(Recipe): - version = '' + version = '3.5' url = '' name = 'python3crystax' - depends = ['hostpython3'] + depends = ['hostpython3crystax'] conflicts = ['python2', 'python3'] - def __init__(self, **kwargs): - super(Python3Recipe, self).__init__(**kwargs) - self.crystax = lambda *args: True if self.ctx.ndk_is_crystax else False + def get_dir_name(self): + name = super(Python3Recipe, self).get_dir_name() + name += '-version{}'.format(self.version) + return name def prebuild_arch(self, arch): - self.ctx.ensure_crystax_python_install_dir() + if not self.ctx.ndk_is_crystax: + error('The python3crystax recipe can only be built when ' + 'using the CrystaX NDK. Exiting.') + exit(1) def build_arch(self, arch): - info('doing nothing, the crystax python3 is included in the ndk!') - + info('Extracting CrystaX python3 from NDK package') + # This is necessary (I think?) in order for the + # cross-compilation to work + + dirn = self.ctx.get_python_install_dir() + ensure_dir(dirn) + # ensure_dir(join(dirn, 'lib')) + # ensure_dir(join(dirn, 'lib', 'python{}'.format(self.version), + # 'site-packages')) + + # ndk_dir = self.ctx.ndk_dir + # sh.cp('-r', '/home/asandy/kivytest/crystax_stdlib', join(dirn, 'lib', 'python3.5')) + # sh.cp('-r', '/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/libs/armeabi/modules', join(dirn, 'lib', 'python3.5', 'lib-dynload')) + # ensure_dir(join(dirn, 'lib', 'site-packages')) recipe = Python3Recipe() From 6534656380ec1133cbae4d8ab9057b64d6770a67 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Thu, 24 Dec 2015 15:29:51 +0000 Subject: [PATCH 09/43] Modified CythonRecipe to work with crystax build --- pythonforandroid/recipe.py | 47 +++++++++++++------ .../recipes/python3crystax/__init__.py | 2 - 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index c88a13e8df..3c60aa44b0 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -815,9 +815,17 @@ def build_arch(self, arch): def build_cython_components(self, arch): info('Cythonizing anything necessary in {}'.format(self.name)) + env = self.get_recipe_env(arch) - # env['PYTHONHOME'] = self.ctx.get_python_install_dir() - env['PYTHONPATH'] = '/usr/lib/python3.5/site-packages/:/usr/lib/python3.5' + + if self.ctx.ndk_is_crystax: + site_packages_dirs = sh.Command('python3.5')('-c', 'import site; print("\\n".join(site.getsitepackages()))').stdout.split('\n') + # env['PYTHONPATH'] = '/usr/lib/python3.5/site-packages/:/usr/lib/python3.5' + if 'PYTHONPATH' in env: + env['PYTHONPATH'] = env + ':{}'.format(':'.join(site_packages_dirs)) + else: + env['PYTHONPATH'] = ':'.join(site_packages_dirs) + with current_directory(self.get_build_dir(arch.arch)): # hostpython = sh.Command(self.ctx.hostpython) hostpython = sh.Command('python3.5') @@ -825,27 +833,36 @@ def build_cython_components(self, arch): print('cwd is', realpath(curdir)) info('Trying first build of {} to get cython files: this is ' 'expected to fail'.format(self.name)) + + manually_cythonise = False try: - shprint(hostpython, 'setup.py', 'build_ext', _env=env, + shprint(hostpython, 'setup.py', 'build_ext', '-v', _env=env, *self.setup_extra_args) except sh.ErrorReturnCode_1: print() info('{} first build failed (as expected)'.format(self.name)) + manually_cythonise = True - info('Running cython where appropriate') - # shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', - # '-exec', self.ctx.cython, '{}', ';', _env=env) - shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', - '-exec', self.ctx.cython, '{}', ';') - info('ran cython') + if manually_cythonise: + info('Running cython where appropriate') + if self.ctx.ndk_is_crystax: + shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', + '-exec', self.ctx.cython, '{}', ';') + else: + shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', + '-exec', self.ctx.cython, '{}', ';', _env=env) + info('ran cython') - shprint(hostpython, 'setup.py', 'build_ext', '-v', _env=env, - _tail=20, _critical=True, *self.setup_extra_args) + shprint(hostpython, 'setup.py', 'build_ext', '-v', _env=env, + _tail=20, _critical=True, *self.setup_extra_args) + else: + info('First build appeared to complete correctly, skipping manual' + 'cythonising.') - # print('stripping') - # build_lib = glob.glob('./build/lib*') - # shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', - # env['STRIP'], '{}', ';', _env=env) + print('stripping') + build_lib = glob.glob('./build/lib*') + shprint(sh.find, build_lib[0], '-name', '*.o', '-exec', + env['STRIP'], '{}', ';', _env=env) print('stripped!?') # exit(1) diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py index e1e35997ca..94366d6555 100644 --- a/pythonforandroid/recipes/python3crystax/__init__.py +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -28,8 +28,6 @@ def prebuild_arch(self, arch): def build_arch(self, arch): info('Extracting CrystaX python3 from NDK package') - # This is necessary (I think?) in order for the - # cross-compilation to work dirn = self.ctx.get_python_install_dir() ensure_dir(dirn) From d1bd689b208988fe277381e1f85d3c275523538e Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Thu, 24 Dec 2015 15:54:20 +0000 Subject: [PATCH 10/43] Changed cython call for crystax build --- pythonforandroid/recipe.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 3c60aa44b0..de395f7860 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -847,7 +847,8 @@ def build_cython_components(self, arch): info('Running cython where appropriate') if self.ctx.ndk_is_crystax: shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', - '-exec', self.ctx.cython, '{}', ';') + '-exec', 'cython', '{}', ';') + # AND: Need to choose cython version more carefully else: shprint(sh.find, self.get_build_dir(arch.arch), '-iname', '*.pyx', '-exec', self.ctx.cython, '{}', ';', _env=env) From 26711fdbe59039a6181dc82994c803316c094617 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sun, 27 Dec 2015 19:33:51 +0000 Subject: [PATCH 11/43] Added py3 support notice in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c20715c5b2..7bbb8f5dfc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Broad goals of the revamp project include: - ✓ Support SDL2 - ✓ Support multiple bootstraps (user-chosen java + NDK code, e.g. for multiple graphics backends or non-Kivy projects) -- (WIP) Support python3 (recipe exists but crashes on android) +- ✓ Support python3 (it finally works!) - (WIP) Support some kind of binary distribution, including on windows (semi-implemented, just needs finishing) - ✓ Be a standalone Pypi module (not on pypi yet but setup.py works) - ✓ Support multiple architectures (full multiarch builds not complete, but arm and x86 with different config both work now) From 226e3cb7692d99594bff76fc1c42557a24c34c9e Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sun, 3 Jan 2016 22:00:24 +0000 Subject: [PATCH 12/43] Modified SDL2 bootstrap for crystax --- pythonforandroid/bootstraps/sdl2/__init__.py | 4 +++- pythonforandroid/bootstraps/sdl2/build/build.py | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pythonforandroid/bootstraps/sdl2/__init__.py b/pythonforandroid/bootstraps/sdl2/__init__.py index 33871a2d10..7e980d623c 100644 --- a/pythonforandroid/bootstraps/sdl2/__init__.py +++ b/pythonforandroid/bootstraps/sdl2/__init__.py @@ -28,8 +28,10 @@ def run_distribute(self): with current_directory(self.dist_dir): info('Copying python distribution') - if not exists('private'): + if not exists('private') and not self.ctx.ndk_is_crystax: shprint(sh.mkdir, 'private') + if not exists('crystax_python') and self.ctx..ndk_is_crystax: + shprint(sh.mkdir, 'crytax_python') if not exists('assets'): shprint(sh.mkdir, 'assets') diff --git a/pythonforandroid/bootstraps/sdl2/build/build.py b/pythonforandroid/bootstraps/sdl2/build/build.py index 16c53b6683..9249491d51 100755 --- a/pythonforandroid/bootstraps/sdl2/build/build.py +++ b/pythonforandroid/bootstraps/sdl2/build/build.py @@ -2,7 +2,7 @@ from __future__ import print_function -from os.path import dirname, join, isfile, realpath, relpath, split +from os.path import dirname, join, isfile, realpath, relpath, split, exists import os import tarfile import time @@ -107,6 +107,12 @@ def make_python_zip(): # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html site-packages, config and lib-dynload will be not included. ''' + + if not exists('private'): + print('No compiled python is present to zip, skipping.') + print('this should only be the case if you are using the CrystaX python') + return + global python_files d = realpath(join('private', 'lib', 'python2.7')) @@ -215,13 +221,18 @@ def make_package(args): os.unlink('assets/private.mp3') # In order to speedup import and initial depack, - # construct a python27.zip + # construct a python27.zip if not using CrystaX's pre-zipped package make_python_zip() # Package up the private and public data. # AND: Just private for now + tar_dirs = [args.private] + if exists('private'): + tar_dirs.append('private') + if exists('crystax_python'): + tar_dirs.append('crystax_python') if args.private: - make_tar('assets/private.mp3', ['private', args.private], args.ignore_path) + make_tar('assets/private.mp3', tar_dirs, args.ignore_path) # else: # make_tar('assets/private.mp3', ['private']) From c4e2b89889382101a27ea61325a2c97e258637bf Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sun, 3 Jan 2016 22:00:55 +0000 Subject: [PATCH 13/43] Added python3crystax alternative dep for sdl2 --- pythonforandroid/recipe.py | 6 ++++-- pythonforandroid/recipes/sdl2/__init__.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index de395f7860..0f63f99f66 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -887,8 +887,10 @@ def get_recipe_env(self, arch): env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format( self.ctx.get_libs_dir(arch.arch) + ' -L{} '.format(self.ctx.libs_dir)) + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2python3crystax/libs/armeabi ' - # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') - env['LDSHARED'] = env['CC'] + ' -shared' + if self.ctx.ndk_is_crystax: + env['LDSHARED'] = env['CC'] + ' -shared' + else: + env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') shprint(sh.whereis, env['LDSHARED'], _env=env) env['LIBLINK'] = 'NOTNONE' env['NDKPLATFORM'] = self.ctx.ndk_platform diff --git a/pythonforandroid/recipes/sdl2/__init__.py b/pythonforandroid/recipes/sdl2/__init__.py index 7ca4c4a368..fbc88bd6e6 100644 --- a/pythonforandroid/recipes/sdl2/__init__.py +++ b/pythonforandroid/recipes/sdl2/__init__.py @@ -9,7 +9,7 @@ class LibSDL2Recipe(BootstrapNDKRecipe): dir_name = 'SDL' - depends = ['python2', 'sdl2_image', 'sdl2_mixer', 'sdl2_ttf'] + depends = [('python2', 'python3crystax'), 'sdl2_image', 'sdl2_mixer', 'sdl2_ttf'] conflicts = ['sdl', 'pygame', 'pygame_bootstrap_components'] patches = ['add_nativeSetEnv.patch'] From 1f2612b35609320a9f8037419054c53e08e264b9 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Mon, 4 Jan 2016 19:52:37 +0000 Subject: [PATCH 14/43] Modfied SDL2 recipe and bootstrap for python3 --- pythonforandroid/bootstrap.py | 3 + pythonforandroid/bootstraps/sdl2/__init__.py | 88 ++++++----- .../bootstraps/sdl2/build/jni/src/Android.mk | 10 +- .../bootstraps/sdl2/build/jni/src/start.c | 138 ++++++++++++++---- pythonforandroid/recipe.py | 7 +- pythonforandroid/recipes/pyjnius/__init__.py | 4 +- 6 files changed, 178 insertions(+), 72 deletions(-) diff --git a/pythonforandroid/bootstrap.py b/pythonforandroid/bootstrap.py index cedf50df28..e9c823e606 100644 --- a/pythonforandroid/bootstrap.py +++ b/pythonforandroid/bootstrap.py @@ -216,6 +216,9 @@ def _unpack_aar(self, aar, arch): def strip_libraries(self, arch): info('Stripping libraries') + if self.ctx.ndk_is_crystax: + info('NDK is CrystaX, skipping') + return env = arch.get_env() strip = which('arm-linux-androideabi-strip', env['PATH']) if strip is None: diff --git a/pythonforandroid/bootstraps/sdl2/__init__.py b/pythonforandroid/bootstraps/sdl2/__init__.py index 7e980d623c..c2a06e79e4 100644 --- a/pythonforandroid/bootstraps/sdl2/__init__.py +++ b/pythonforandroid/bootstraps/sdl2/__init__.py @@ -30,57 +30,69 @@ def run_distribute(self): if not exists('private') and not self.ctx.ndk_is_crystax: shprint(sh.mkdir, 'private') - if not exists('crystax_python') and self.ctx..ndk_is_crystax: - shprint(sh.mkdir, 'crytax_python') + if not exists('crystax_python') and self.ctx.ndk_is_crystax: + shprint(sh.mkdir, 'crystax_python') if not exists('assets'): shprint(sh.mkdir, 'assets') hostpython = sh.Command(self.ctx.hostpython) - shprint(hostpython, '-OO', '-m', 'compileall', - self.ctx.get_python_install_dir(), - _tail=10, _filterout="^Listing", _critical=True) - if not exists('python-install'): - shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install') + if not self.ctx.ndk_is_crystax: + shprint(hostpython, '-OO', '-m', 'compileall', + self.ctx.get_python_install_dir(), + _tail=10, _filterout="^Listing", _critical=True) + if not exists('python-install'): + shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install') self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)]) self.distribute_aars(arch) self.distribute_javaclasses(self.ctx.javaclass_dir) - info('Filling private directory') - if not exists(join('private', 'lib')): - info('private/lib does not exist, making') - shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') - shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7')) + if not self.ctx.ndk_is_crystax: + info('Filling private directory') + if not exists(join('private', 'lib')): + info('private/lib does not exist, making') + shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') + shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7')) - # AND: Copylibs stuff should go here - if exists(join('libs', arch.arch, 'libpymodules.so')): - shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/') - shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/')) + # AND: Copylibs stuff should go here + if exists(join('libs', arch.arch, 'libpymodules.so')): + shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/') + shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/')) - info('Removing some unwanted files') - shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so')) - shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) + info('Removing some unwanted files') + shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so')) + shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) - with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')): - # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) - removes = [] - for dirname, something, filens in walk('.'): - for filename in filens: - for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): - if filename.endswith(suffix): - removes.append(filename) - shprint(sh.rm, '-f', *removes) + with current_directory(join(self.dist_dir, 'private', 'lib', 'python2.7')): + # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) + removes = [] + for dirname, something, filens in walk('.'): + for filename in filens: + for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): + if filename.endswith(suffix): + removes.append(filename) + shprint(sh.rm, '-f', *removes) - info('Deleting some other stuff not used on android') - # To quote the original distribute.sh, 'well...' - # shprint(sh.rm, '-rf', 'ctypes') - shprint(sh.rm, '-rf', 'lib2to3') - shprint(sh.rm, '-rf', 'idlelib') - for filename in glob.glob('config/libpython*.a'): - shprint(sh.rm, '-f', filename) - shprint(sh.rm, '-rf', 'config/python.o') - # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') - # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') + info('Deleting some other stuff not used on android') + # To quote the original distribute.sh, 'well...' + # shprint(sh.rm, '-rf', 'ctypes') + shprint(sh.rm, '-rf', 'lib2to3') + shprint(sh.rm, '-rf', 'idlelib') + for filename in glob.glob('config/libpython*.a'): + shprint(sh.rm, '-f', filename) + shprint(sh.rm, '-rf', 'config/python.o') + # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') + # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') + + else: # NDK *is* crystax + ndk_dir = self.ctx.ndk_dir + python_dir = join(ndk_dir, 'sources', 'python', '3.5', + 'libs', arch.arch) + + shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/') + shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/') + shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/site-packages') + self.strip_libraries(arch) super(SDL2Bootstrap, self).run_distribute() diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk index 6c90a3b818..06f197e3b7 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk @@ -12,12 +12,14 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ start.c -LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 +# LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 -LOCAL_SHARED_LIBRARIES := SDL2 +LOCAL_SHARED_LIBRARIES := SDL2 python_shared -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lpython2.7 +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog #-lpython2.7 -LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) +# LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) include $(BUILD_SHARED_LIBRARY) + +$(call import-module,python/3.5) diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index 5119d92b82..59a8fb7269 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -39,8 +39,32 @@ static PyMethodDef AndroidEmbedMethods[] = { {NULL, NULL, 0, NULL} }; +static struct PyModuleDef androidembed = + { + PyModuleDef_HEAD_INIT, + "androidembed", + "", + -1, + AndroidEmbedMethods + }; + PyMODINIT_FUNC initandroidembed(void) { - (void) Py_InitModule("androidembed", AndroidEmbedMethods); + return PyModule_Create(&androidembed); + /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ +} + +int dir_exists(char* filename) + /* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# */ +{ + if (0 != access("filename", F_OK)) { + if (ENOENT == errno) { + return 0; + } + if (ENOTDIR == errno) { + return 0; + } + return 1; + } } int file_exists(const char * filename) @@ -78,38 +102,71 @@ int main(int argc, char *argv[]) { /* LOG(argv[0]); */ /* LOG("AND: That was argv 0"); */ //setenv("PYTHONVERBOSE", "2", 1); - Py_SetProgramName(argv[0]); + Py_SetProgramName(L"android_python"); + + /* our logging module for android + */ + PyImport_AppendInittab("androidembed", initandroidembed); + + if (dir_exists("crystax_python/")) { + char paths[256]; + snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); + /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */ + LOG("calculated paths to be..."); + LOG(paths); + + wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); + Py_SetPath(wchar_paths); + LOG("set wchar paths..."); + } + Py_Initialize(); - PySys_SetArgv(argc, argv); - LOG("AND: Set program name"); + if (dir_exists("private/")) { + PySys_SetArgv(argc, argv); + } + + LOG("Initialized python"); /* ensure threads will work. */ - PyEval_InitThreads(); - LOG("AND: Init threads"); + PyEval_InitThreads(); + - /* our logging module for android - */ - initandroidembed(); - - LOG("AND: Init embed"); + PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')"); + LOG("tried to run simple androidembed test"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ + PyRun_SimpleString("import sys, posix\n"); + if (dir_exists("private/")) { + /* If we built our own python, set up the paths correctly */ + PyRun_SimpleString( + "private = posix.environ['ANDROID_PRIVATE']\n" \ + "argument = posix.environ['ANDROID_ARGUMENT']\n" \ + "sys.path[:] = [ \n" \ + " private + '/lib/python27.zip', \n" \ + " private + '/lib/python2.7/', \n" \ + " private + '/lib/python2.7/lib-dynload/', \n" \ + " private + '/lib/python2.7/site-packages/', \n" \ + " argument ]\n"); + } else { + + char add_site_packages_dir[256]; + snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", + env_argument); + + PyRun_SimpleString( + "import sys\n" \ + "sys.argv = ['notaninterpreterreally']\n" \ + "from os.path import realpath, join, dirname"); + PyRun_SimpleString(add_site_packages_dir); + /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ + } + PyRun_SimpleString( - "import sys, posix\n" \ - "private = posix.environ['ANDROID_PRIVATE']\n" \ - "argument = posix.environ['ANDROID_ARGUMENT']\n" \ - "sys.path[:] = [ \n" \ - " private + '/lib/python27.zip', \n" \ - " private + '/lib/python2.7/', \n" \ - " private + '/lib/python2.7/lib-dynload/', \n" \ - " private + '/lib/python2.7/site-packages/', \n" \ - " argument ]\n" \ - "import androidembed\n" \ "class LogFile(object):\n" \ " def __init__(self):\n" \ " self.buffer = ''\n" \ @@ -122,9 +179,37 @@ int main(int argc, char *argv[]) { " def flush(self):\n" \ " return\n" \ "sys.stdout = sys.stderr = LogFile()\n" \ - "import site; print site.getsitepackages()\n"\ - "print 'Android path', sys.path\n" \ - "print 'Android kivy bootstrap done. __name__ is', __name__"); + "print('Android path', sys.path)\n" \ + "import os\n" \ + "print('os.environ is', os.environ)\n" \ + "print('Android kivy bootstrap done. __name__ is', __name__)"); + + /* PyRun_SimpleString( */ + /* "import sys, posix\n" \ */ + /* "private = posix.environ['ANDROID_PRIVATE']\n" \ */ + /* "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */ + /* "sys.path[:] = [ \n" \ */ + /* " private + '/lib/python27.zip', \n" \ */ + /* " private + '/lib/python2.7/', \n" \ */ + /* " private + '/lib/python2.7/lib-dynload/', \n" \ */ + /* " private + '/lib/python2.7/site-packages/', \n" \ */ + /* " argument ]\n" \ */ + /* "import androidembed\n" \ */ + /* "class LogFile(object):\n" \ */ + /* " def __init__(self):\n" \ */ + /* " self.buffer = ''\n" \ */ + /* " def write(self, s):\n" \ */ + /* " s = self.buffer + s\n" \ */ + /* " lines = s.split(\"\\n\")\n" \ */ + /* " for l in lines[:-1]:\n" \ */ + /* " androidembed.log(l)\n" \ */ + /* " self.buffer = lines[-1]\n" \ */ + /* " def flush(self):\n" \ */ + /* " return\n" \ */ + /* "sys.stdout = sys.stderr = LogFile()\n" \ */ + /* "import site; print site.getsitepackages()\n"\ */ + /* "print 'Android path', sys.path\n" \ */ + /* "print 'Android kivy bootstrap done. __name__ is', __name__"); */ LOG("AND: Ran string"); /* run it ! @@ -160,8 +245,9 @@ int main(int argc, char *argv[]) { if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ - if (Py_FlushLine()) - PyErr_Clear(); + PyObject *f = PySys_GetObject("stdout"); + if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ + PyErr_Clear(); } /* close everything diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 0f63f99f66..ef95a1495f 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -886,7 +886,9 @@ def get_recipe_env(self, arch): env = super(CythonRecipe, self).get_recipe_env(arch) env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format( self.ctx.get_libs_dir(arch.arch) + - ' -L{} '.format(self.ctx.libs_dir)) + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2python3crystax/libs/armeabi ' + ' -L{} '.format(self.ctx.libs_dir)) + if self.ctx.ndk_is_crystax: + env['LDFLAGS'] = env['LDFLAGS'] + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2/libs/armeabi ' if self.ctx.ndk_is_crystax: env['LDSHARED'] = env['CC'] + ' -shared' else: @@ -902,6 +904,7 @@ def get_recipe_env(self, arch): env['LIBLINK_PATH'] = liblink_path ensure_dir(liblink_path) - env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS'] + if self.ctx.ndk_is_crystax: + env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS'] return env diff --git a/pythonforandroid/recipes/pyjnius/__init__.py b/pythonforandroid/recipes/pyjnius/__init__.py index 31e85ed830..740e6cba69 100644 --- a/pythonforandroid/recipes/pyjnius/__init__.py +++ b/pythonforandroid/recipes/pyjnius/__init__.py @@ -1,6 +1,6 @@ from pythonforandroid.toolchain import CythonRecipe, shprint, current_directory, info -from pythonforandroid.patching import will_build +from pythonforandroid.patching import will_build, check_any import sh from os.path import join @@ -12,7 +12,7 @@ class PyjniusRecipe(CythonRecipe): depends = [('python2', 'python3crystax'), ('sdl2', 'sdl', 'sdl2python3crystax'), 'six'] site_packages_name = 'jnius' - patches = [('sdl2_jnienv_getter.patch', will_build('sdl2python3crystax')), + patches = [('sdl2_jnienv_getter.patch', check_any(will_build('sdl2python3crystax'), will_build('sdl2'))), 'getenv.patch'] def postbuild_arch(self, arch): From 411555dfb9e78b8f15417e80b5b5166202eda9d7 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Wed, 6 Jan 2016 23:13:08 +0000 Subject: [PATCH 15/43] Modified shprint logging --- pythonforandroid/logger.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pythonforandroid/logger.py b/pythonforandroid/logger.py index 43c207ab3d..03940a9f0a 100644 --- a/pythonforandroid/logger.py +++ b/pythonforandroid/logger.py @@ -138,7 +138,9 @@ def shprint(command, *args, **kwargs): columns = get_console_width() command_path = str(command).split('/') command_string = command_path[-1] - string = ' '.join(['running', command_string] + list(args)) + string = ' '.join(['{}->{} running'.format(Out_Fore.LIGHTBLACK_EX, + Out_Style.RESET_ALL), + command_string] + list(args)) # If logging is not in DEBUG mode, trim the command if necessary if logger.level > logging.DEBUG: From 9fb3af2853899954a17e10103746443f525ce26a Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sun, 10 Jan 2016 21:22:40 +0000 Subject: [PATCH 16/43] Added py2/py3 .so load in sdl2 bootstrap --- .../src/org/kivy/android/PythonActivity.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java index 7f754d868e..68359345cb 100644 --- a/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/sdl2/build/src/org/kivy/android/PythonActivity.java @@ -93,7 +93,6 @@ protected String[] getLibraries() { "SDL2_image", "SDL2_mixer", "SDL2_ttf", - "python2.7", "main" }; } @@ -104,9 +103,25 @@ public void loadLibraries() { System.loadLibrary(lib); } - System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); - System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); - + try { + System.loadLibrary("python2.7"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load libpython2.7"); + } + + try { + System.loadLibrary("python3.5m"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load libpython3.5m"); + } + + try { + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); + } catch(UnsatisfiedLinkError e) { + Log.v(TAG, "Failed to load _io.so or unicodedata.so...but that's okay."); + } + try { // System.loadLibrary("ctypes"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); From 76bcf99da33803594b3db153ee15b12acf829aef Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Wed, 6 Jan 2016 23:26:25 +0000 Subject: [PATCH 17/43] More sdl2 bootstrap changes for python3 --- pythonforandroid/bootstraps/sdl2/__init__.py | 18 ++++-- .../bootstraps/sdl2/build/jni/src/start.c | 55 ++++++++++++++----- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/pythonforandroid/bootstraps/sdl2/__init__.py b/pythonforandroid/bootstraps/sdl2/__init__.py index c2a06e79e4..6816e674de 100644 --- a/pythonforandroid/bootstraps/sdl2/__init__.py +++ b/pythonforandroid/bootstraps/sdl2/__init__.py @@ -32,6 +32,7 @@ def run_distribute(self): shprint(sh.mkdir, 'private') if not exists('crystax_python') and self.ctx.ndk_is_crystax: shprint(sh.mkdir, 'crystax_python') + shprint(sh.mkdir, 'crystax_python/crystax_python') if not exists('assets'): shprint(sh.mkdir, 'assets') @@ -89,10 +90,19 @@ def run_distribute(self): python_dir = join(ndk_dir, 'sources', 'python', '3.5', 'libs', arch.arch) - shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/') - shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/') - shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/site-packages') - + shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/crystax_python') + shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/crystax_python') + shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/crystax_python/site-packages') + + info('Renaming .so files to reflect cross-compile') + site_packages_dir = 'crystax_python/crystax_python/site-packages' + filens = shprint(sh.find, site_packages_dir, '-iname', '*.so').stdout.split('\n')[:-1] + for filen in filens: + parts = filen.split('.') + if len(parts) <= 2: + continue + shprint(sh.mv, filen, filen.split('.')[0] + '.so') + self.strip_libraries(arch) super(SDL2Bootstrap, self).run_distribute() diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index 59a8fb7269..a1543c8bdc 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "SDL.h" @@ -53,18 +54,27 @@ PyMODINIT_FUNC initandroidembed(void) { /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ } -int dir_exists(char* filename) - /* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# */ -{ - if (0 != access("filename", F_OK)) { - if (ENOENT == errno) { - return 0; - } - if (ENOTDIR == errno) { - return 0; - } +/* int dir_exists(char* filename) */ +/* /\* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# *\/ */ +/* { */ +/* if (0 != access(filename, F_OK)) { */ +/* if (ENOENT == errno) { */ +/* return 0; */ +/* } */ +/* if (ENOTDIR == errno) { */ +/* return 0; */ +/* } */ +/* return 1; */ +/* } */ +/* } */ + +int dir_exists(char* filename) { + DIR *dip; + if (dip = opendir(filename)) { + closedir(filename); return 1; } + return 0; } int file_exists(const char * filename) @@ -108,7 +118,21 @@ int main(int argc, char *argv[]) { */ PyImport_AppendInittab("androidembed", initandroidembed); + LOG("Preparing to initialize python"); + + if (dir_exists("../libs")) { + LOG("libs exists"); + } else { + LOG("libs does not exist"); + } + + if (dir_exists("crystax_python")) { + LOG("exists without slash"); + } + if (dir_exists("crystax_python/")) { + /* if (1) { */ + LOG("crystax_python exists"); char paths[256]; snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */ @@ -118,7 +142,7 @@ int main(int argc, char *argv[]) { wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); LOG("set wchar paths..."); - } + } else { LOG("crystax_python does not exist");} Py_Initialize(); @@ -152,18 +176,19 @@ int main(int argc, char *argv[]) { " private + '/lib/python2.7/lib-dynload/', \n" \ " private + '/lib/python2.7/site-packages/', \n" \ " argument ]\n"); - } else { + } else { char add_site_packages_dir[256]; snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", env_argument); PyRun_SimpleString( - "import sys\n" \ - "sys.argv = ['notaninterpreterreally']\n" \ + "import sys\n" \ + "sys.argv = ['notaninterpreterreally']\n" \ "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); - /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ + /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ + PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( From 6d7e4b1d15735f05a0eabe387265e3901eebb4dc Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Thu, 7 Jan 2016 23:17:47 +0000 Subject: [PATCH 18/43] Moved chdir in SDL2 start.c --- .../bootstraps/sdl2/build/jni/src/start.c | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index a1543c8bdc..e10fb9173c 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -10,6 +10,10 @@ #include #include #include +#include +#include + +#include #include "SDL.h" @@ -68,15 +72,26 @@ PyMODINIT_FUNC initandroidembed(void) { /* } */ /* } */ -int dir_exists(char* filename) { - DIR *dip; - if (dip = opendir(filename)) { - closedir(filename); - return 1; +/* int dir_exists(char* filename) { */ +/* DIR *dip; */ +/* if (dip = opendir(filename)) { */ +/* closedir(filename); */ +/* return 1; */ +/* } */ +/* return 0; */ +/* } */ + + +int dir_exists(char *filename) { + struct stat st; + if (stat(filename, &st) == 0) { + if (S_ISDIR(st.st_mode)) + return 1; } return 0; } + int file_exists(const char * filename) { FILE *file; @@ -112,6 +127,12 @@ int main(int argc, char *argv[]) { /* LOG(argv[0]); */ /* LOG("AND: That was argv 0"); */ //setenv("PYTHONVERBOSE", "2", 1); + + LOG("Changing directory to the one provided by ANDROID_ARGUMENT"); + LOG(env_argument); + chdir(env_argument); + + Py_SetProgramName(L"android_python"); /* our logging module for android @@ -120,14 +141,31 @@ int main(int argc, char *argv[]) { LOG("Preparing to initialize python"); + char errstr[256]; + snprintf(errstr, 256, "errno before is %d", + errno); + LOG(errstr); + + if (dir_exists("crystax_python")) { + LOG("exists without slash"); + } + + snprintf(errstr, 256, "errno after is %d", + errno); + LOG(errstr); + if (dir_exists("../libs")) { LOG("libs exists"); } else { LOG("libs does not exist"); } + + if (file_exists("main.py")) { + LOG("The main.py does exist"); + } - if (dir_exists("crystax_python")) { - LOG("exists without slash"); + if (file_exists("main.py") == 1) { + LOG("The main.py does exist2"); } if (dir_exists("crystax_python/")) { @@ -240,7 +278,6 @@ int main(int argc, char *argv[]) { /* run it ! */ LOG("Run user program, change dir and execute main.py"); - chdir(env_argument); /* search the initial main.py */ From 6ef2fe72c2fdf6f3d6a4e5d700e7f57f68d333bd Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Fri, 8 Jan 2016 23:29:09 +0000 Subject: [PATCH 19/43] Removed testgles2.c from git --- .../bootstraps/sdl2/build/jni/src/testgles2.c | 695 ------------------ 1 file changed, 695 deletions(-) delete mode 100644 pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c deleted file mode 100644 index ef9f38d607..0000000000 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/testgles2.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - Copyright (r) 1997-2014 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES2 -#endif - -#ifdef HAVE_OPENGLES2 - -#include "SDL_opengles2.h" - -typedef struct GLES2_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC -} GLES2_Context; - - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; -static GLES2_Context ctx; - -static int LoadContext(GLES2_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* _SDL_NOGETPROCADDR_ */ - -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC - return 0; -} - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -#define GL_CHECK(x) \ - x; \ - { \ - GLenum glError = ctx.glGetError(); \ - if(glError != GL_NO_ERROR) { \ - SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ - quit(1); \ - } \ - } - -/* - * Simulates desktop's glRotatef. The matrix is returned in column-major - * order. - */ -static void -rotate_matrix(double angle, double x, double y, double z, float *r) -{ - double radians, c, s, c1, u[3], length; - int i, j; - - radians = (angle * M_PI) / 180.0; - - c = cos(radians); - s = sin(radians); - - c1 = 1.0 - cos(radians); - - length = sqrt(x * x + y * y + z * z); - - u[0] = x / length; - u[1] = y / length; - u[2] = z / length; - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[15] = 1.0; - - for (i = 0; i < 3; i++) { - r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; - r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; - } - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0); - } - } -} - -/* - * Simulates gluPerspectiveMatrix - */ -static void -perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r) -{ - int i; - double f; - - f = 1.0/tan(fovy * 0.5); - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[0] = f / aspect; - r[5] = f; - r[10] = (znear + zfar) / (znear - zfar); - r[11] = -1.0; - r[14] = (2.0 * znear * zfar) / (znear - zfar); - r[15] = 0.0; -} - -/* - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column - * major. In-place multiplication is supported. - */ -static void -multiply_matrix(float *lhs, float *rhs, float *r) -{ - int i, j, k; - float tmp[16]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - tmp[j * 4 + i] = 0.0; - - for (k = 0; k < 4; k++) { - tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; - } - } - } - - for (i = 0; i < 16; i++) { - r[i] = tmp[i]; - } -} - -/* - * Create shader, load in source, compile, dump debug as necessary. - * - * shader: Pointer to return created shader ID. - * source: Passed-in shader source code. - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. - */ -void -process_shader(GLuint *shader, const char * source, GLint shader_type) -{ - GLint status = GL_FALSE; - const char *shaders[1] = { NULL }; - - /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); - - shaders[0] = source; - - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); - - /* Clean up shader source. */ - shaders[0] = NULL; - - /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); - - // Dump debug info (source and log) if compilation failed. - if(status != GL_TRUE) { - SDL_Log("Shader compilation failed"); - quit(-1); - } -} - -/* 3D data. Vertex range -0.5..0.5 in all axes. -* Z -0.5 is near, 0.5 is far. */ -const float _vertices[] = -{ - /* Front face. */ - /* Bottom left */ - -0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top right */ - -0.5, 0.5, -0.5, - 0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - /* Left face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - -0.5, -0.5, -0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, 0.5, 0.5, - -0.5, 0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, -0.5, - /* Top right */ - -0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - /* Right face */ - /* Bottom left */ - 0.5, 0.5, -0.5, - 0.5, -0.5, 0.5, - 0.5, -0.5, -0.5, - /* Top right */ - 0.5, 0.5, -0.5, - 0.5, 0.5, 0.5, - 0.5, -0.5, 0.5, - /* Back face */ - /* Bottom left */ - 0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - 0.5, -0.5, 0.5, - /* Top right */ - 0.5, 0.5, 0.5, - -0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - /* Bottom face */ - /* Bottom left */ - -0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, -}; - -const float _colors[] = -{ - /* Front face */ - /* Bottom left */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 1.0, /* blue */ - 0.0, 1.0, 0.0, /* green */ - /* Top right */ - 1.0, 0.0, 0.0, /* red */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 1.0, /* blue */ - /* Left face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 1.0, 0.0, /* green */ - /* Top face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 0.0, /* red */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 0.0, /* yellow */ - /* Right face */ - /* Bottom left */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - /* Top right */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 0.0, 1.0, /* magenta */ - /* Back face */ - /* Bottom left */ - 0.0, 0.0, 0.0, /* black */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - /* Top right */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - /* Bottom face */ - /* Bottom left */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 0.0, 1.0, /* magenta */ -}; - -const char* _shader_vert_src = -" attribute vec4 av4position; " -" attribute vec3 av3color; " -" uniform mat4 mvp; " -" varying vec3 vv3color; " -" void main() { " -" vv3color = av3color; " -" gl_Position = mvp * av4position; " -" } "; - -const char* _shader_frag_src = -" precision lowp float; " -" varying vec3 vv3color; " -" void main() { " -" gl_FragColor = vec4(vv3color, 1.0); " -" } "; - -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - -} shader_data; - -static void -Render(unsigned int width, unsigned int height, shader_data* data) -{ - float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; - - /* - * Do some rotation with Euler angles. It is not a fixed axis as - * quaterions would be, but the effect is cool. - */ - rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview); - rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - /* Pull the camera back from the cube */ - matrix_modelview[14] -= 2.5; - - perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective); - multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); - - data->angle_x += 3; - data->angle_y += 2; - data->angle_z += 1; - - if(data->angle_x >= 360) data->angle_x -= 360; - if(data->angle_x < 0) data->angle_x += 360; - if(data->angle_y >= 360) data->angle_y -= 360; - if(data->angle_y < 0) data->angle_y += 360; - if(data->angle_z >= 360) data->angle_z -= 360; - if(data->angle_z < 0) data->angle_z += 360; - - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - shader_data *datas, *data; - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], - SDLTest_CommonUsage(state)); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 2; - state->gl_minor_version = 0; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - return 0; - } - - context = SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_Log("Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GLES2 functions\n"); - quit(2); - return 0; - } - - - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - datas = SDL_calloc(state->num_windows, sizeof(shader_data)); - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - ctx.glViewport(0, 0, state->window_w, state->window_h); - - data = &datas[i]; - data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; - - /* Shader Initialization */ - process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); - process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); - - /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); - - /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); - - /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); - - /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); - - GL_CHECK(ctx.glUseProgram(data->shader_program)); - - /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); - - /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event) && !done) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - ctx.glViewport(0, 0, event.window.data1, event.window.data2); - /* Update window content */ - Render(event.window.data1, event.window.data2, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - if (!done) { - for (i = 0; i < state->num_windows; ++i) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(state->window_w, state->window_h, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - } - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES2 */ - -int -main(int argc, char *argv[]) -{ - SDL_Log("No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES2 */ - -/* vi: set ts=4 sw=4 expandtab: */ From 1ed06a3ec741ebe72544b5e3251a248fca3052b1 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 19:49:51 +0000 Subject: [PATCH 20/43] Fixed sdl2 bootstrap to work with both py2 and py3 --- pythonforandroid/archs.py | 7 +- .../bootstraps/sdl2/build/jni/src/Android.mk | 10 ++- .../bootstraps/sdl2/build/jni/src/start.c | 78 ++++++++----------- .../bootstraps/sdl2python3crystax/__init__.py | 2 +- pythonforandroid/build.py | 2 + pythonforandroid/recipe.py | 40 ++++++++-- pythonforandroid/recipes/pysdl2/__init__.py | 2 +- pythonforandroid/recipes/python2/__init__.py | 7 +- .../recipes/python3crystax/__init__.py | 9 ++- pythonforandroid/recipes/sdl2/__init__.py | 2 + pythonforandroid/tools/liblink | 3 +- 11 files changed, 98 insertions(+), 64 deletions(-) diff --git a/pythonforandroid/archs.py b/pythonforandroid/archs.py index 774f23f71f..61ae3a7583 100644 --- a/pythonforandroid/archs.py +++ b/pythonforandroid/archs.py @@ -84,8 +84,8 @@ def get_env(self): env['AR'] = '{}-ar'.format(command_prefix) env['RANLIB'] = '{}-ranlib'.format(command_prefix) env['LD'] = '{}-ld'.format(command_prefix) - # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') - env['LDSHARED'] = env['LD'] + # env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') + # env['LDSHARED'] = env['LD'] env['STRIP'] = '{}-strip --strip-unneeded'.format(command_prefix) env['MAKE'] = 'make -j5' env['READELF'] = '{}-readelf'.format(command_prefix) @@ -102,6 +102,9 @@ def get_env(self): env['ARCH'] = self.arch + if self.ctx.ndk_is_crystax: # AND: should use the right python version from the python recipe + env['CRYSTAX_PYTHON_VERSION'] = '3.5' + return env diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk index 06f197e3b7..743282e2d6 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk @@ -12,14 +12,16 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ start.c -# LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 +LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/include/python2.7 LOCAL_SHARED_LIBRARIES := SDL2 python_shared -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog #-lpython2.7 +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog $(EXTRA_LDLIBS) #-lpython2.7 -# LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) +LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) include $(BUILD_SHARED_LIBRARY) -$(call import-module,python/3.5) +ifdef CRYSTAX_PYTHON_VERSION + $(call import-module,python/$(CRYSTAX_PYTHON_VERSION)) +endif diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index e10fb9173c..685d666e57 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -44,19 +44,26 @@ static PyMethodDef AndroidEmbedMethods[] = { {NULL, NULL, 0, NULL} }; -static struct PyModuleDef androidembed = - { - PyModuleDef_HEAD_INIT, - "androidembed", - "", - -1, - AndroidEmbedMethods - }; - -PyMODINIT_FUNC initandroidembed(void) { - return PyModule_Create(&androidembed); - /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ -} + +#if PY_MAJOR_VERSION >= 3 + static struct PyModuleDef androidembed = + { + PyModuleDef_HEAD_INIT, + "androidembed", + "", + -1, + AndroidEmbedMethods + }; + + PyMODINIT_FUNC initandroidembed(void) { + return PyModule_Create(&androidembed); + /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ + } +#else + PyMODINIT_FUNC initandroidembed(void) { + (void) Py_InitModule("androidembed", AndroidEmbedMethods); + } +#endif /* int dir_exists(char* filename) */ /* /\* Function from http://stackoverflow.com/questions/12510874/how-can-i-check-if-a-directory-exists-on-linux-in-c# *\/ */ @@ -132,44 +139,17 @@ int main(int argc, char *argv[]) { LOG(env_argument); chdir(env_argument); - Py_SetProgramName(L"android_python"); +#if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); +#endif LOG("Preparing to initialize python"); - char errstr[256]; - snprintf(errstr, 256, "errno before is %d", - errno); - LOG(errstr); - - if (dir_exists("crystax_python")) { - LOG("exists without slash"); - } - - snprintf(errstr, 256, "errno after is %d", - errno); - LOG(errstr); - - if (dir_exists("../libs")) { - LOG("libs exists"); - } else { - LOG("libs does not exist"); - } - - if (file_exists("main.py")) { - LOG("The main.py does exist"); - } - - if (file_exists("main.py") == 1) { - LOG("The main.py does exist2"); - } - if (dir_exists("crystax_python/")) { - /* if (1) { */ LOG("crystax_python exists"); char paths[256]; snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); @@ -177,8 +157,15 @@ int main(int argc, char *argv[]) { LOG("calculated paths to be..."); LOG(paths); +#if PY_MAJOR_VERSION >= 3 wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); +#else + char* wchar_paths = paths; + LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); + exit(1); +#endif + LOG("set wchar paths..."); } else { LOG("crystax_python does not exist");} @@ -196,8 +183,11 @@ int main(int argc, char *argv[]) { PyEval_InitThreads(); +#if PY_MAJOR_VERSION < 3 + initandroidembed(); +#endif + PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')"); - LOG("tried to run simple androidembed test"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path @@ -215,7 +205,6 @@ int main(int argc, char *argv[]) { " private + '/lib/python2.7/site-packages/', \n" \ " argument ]\n"); } else { - char add_site_packages_dir[256]; snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", env_argument); @@ -275,6 +264,7 @@ int main(int argc, char *argv[]) { /* "print 'Android kivy bootstrap done. __name__ is', __name__"); */ LOG("AND: Ran string"); + /* run it ! */ LOG("Run user program, change dir and execute main.py"); diff --git a/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py b/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py index dfc2dc6cd1..c4667532d8 100644 --- a/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py +++ b/pythonforandroid/bootstraps/sdl2python3crystax/__init__.py @@ -25,7 +25,7 @@ def run_distribute(self): # AND: Hardcoding armeabi - naughty! arch = ArchARM(self.ctx) - with current_directory(self.dist_dir): + with current_directory(self.dist_dir)crystax_python/: info('Copying python distribution') if not exists('private'): diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py index 05c16d931f..0d9c390004 100644 --- a/pythonforandroid/build.py +++ b/pythonforandroid/build.py @@ -446,6 +446,8 @@ def __init__(self): self.env.pop("ARCHFLAGS", None) self.env.pop("CFLAGS", None) + self.python_recipe = None # Set by TargetPythonRecipe + def set_archs(self, arch_names): all_archs = self.archs new_archs = set() diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index ef95a1495f..ae3f5ad8c6 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -679,9 +679,13 @@ class PythonRecipe(Recipe): @property def hostpython_location(self): if not self.call_hostpython_via_targetpython: - return join( - Recipe.get_recipe('hostpython2', self.ctx).get_build_dir(), - 'hostpython') + if 'hostpython2' in self.ctx.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) return self.ctx.hostpython def should_build(self, arch): @@ -715,7 +719,7 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True): with current_directory(self.get_build_dir(arch.arch)): # hostpython = sh.Command(self.ctx.hostpython) hostpython = sh.Command(self.hostpython_location) - hostpython = sh.Command('python3.5') + # hostpython = sh.Command('python3.5') if self.ctx.ndk_is_crystax: @@ -827,8 +831,8 @@ def build_cython_components(self, arch): env['PYTHONPATH'] = ':'.join(site_packages_dirs) with current_directory(self.get_build_dir(arch.arch)): - # hostpython = sh.Command(self.ctx.hostpython) - hostpython = sh.Command('python3.5') + hostpython = sh.Command(self.ctx.hostpython) + # hostpython = sh.Command('python3.5') shprint(hostpython, '-c', 'import sys; print(sys.path)', _env=env) print('cwd is', realpath(curdir)) info('Trying first build of {} to get cython files: this is ' @@ -892,7 +896,7 @@ def get_recipe_env(self, arch): if self.ctx.ndk_is_crystax: env['LDSHARED'] = env['CC'] + ' -shared' else: - env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink-jb') + env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') shprint(sh.whereis, env['LDSHARED'], _env=env) env['LIBLINK'] = 'NOTNONE' env['NDKPLATFORM'] = self.ctx.ndk_platform @@ -908,3 +912,25 @@ def get_recipe_env(self, arch): env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS'] 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) + + @property + def ctx(self): + return self._ctx + + @ctx.setter + def ctx(self, ctx): + self._ctx = ctx + ctx.python_recipe = self diff --git a/pythonforandroid/recipes/pysdl2/__init__.py b/pythonforandroid/recipes/pysdl2/__init__.py index cd22b639ea..36f1527ef5 100644 --- a/pythonforandroid/recipes/pysdl2/__init__.py +++ b/pythonforandroid/recipes/pysdl2/__init__.py @@ -8,7 +8,7 @@ class PySDL2Recipe(PythonRecipe): version = '0.9.3' url = 'https://bitbucket.org/marcusva/py-sdl2/downloads/PySDL2-{version}.tar.gz' - depends = ['sdl2'] + depends = [('sdl2', 'sdl2python3crystax')] recipe = PySDL2Recipe() diff --git a/pythonforandroid/recipes/python2/__init__.py b/pythonforandroid/recipes/python2/__init__.py index c54a465368..2c5100c733 100644 --- a/pythonforandroid/recipes/python2/__init__.py +++ b/pythonforandroid/recipes/python2/__init__.py @@ -1,11 +1,12 @@ -from pythonforandroid.toolchain import Recipe, shprint, current_directory, info +from pythonforandroid.recipe import TargetPythonRecipe, Recipe +from pythonforandroid.toolchain import shprint, current_directory, info from pythonforandroid.patching import is_linux, is_darwin, is_api_gt from os.path import exists, join, realpath import sh -class Python2Recipe(Recipe): +class Python2Recipe(TargetPythonRecipe): version = "2.7.2" url = 'http://python.org/ftp/python/{version}/Python-{version}.tar.bz2' name = 'python2' @@ -33,6 +34,8 @@ class Python2Recipe(Recipe): ('patches/fix-distutils-darwin.patch', is_linux), ('patches/fix-ftime-removal.patch', is_api_gt(19))] + from_crystax = False + def build_arch(self, arch): if not exists(join(self.get_build_dir(arch.arch), 'libpython2.7.so')): diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py index 94366d6555..35531cf77b 100644 --- a/pythonforandroid/recipes/python3crystax/__init__.py +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -1,5 +1,6 @@ -from pythonforandroid.toolchain import Recipe, shprint, current_directory, ArchARM +from pythonforandroid.recipe import TargetPythonRecipe +from pythonforandroid.toolchain import shprint, current_directory, ArchARM from pythonforandroid.logger import info from pythonforandroid.util import ensure_dir from os.path import exists, join @@ -7,7 +8,7 @@ import glob import sh -class Python3Recipe(Recipe): +class Python3Recipe(TargetPythonRecipe): version = '3.5' url = '' name = 'python3crystax' @@ -15,6 +16,8 @@ class Python3Recipe(Recipe): depends = ['hostpython3crystax'] conflicts = ['python2', 'python3'] + from_crystax = True + def get_dir_name(self): name = super(Python3Recipe, self).get_dir_name() name += '-version{}'.format(self.version) @@ -31,6 +34,8 @@ def build_arch(self, arch): dirn = self.ctx.get_python_install_dir() ensure_dir(dirn) + + self.ctx.hostpython = 'python{}'.format(self.version) # ensure_dir(join(dirn, 'lib')) # ensure_dir(join(dirn, 'lib', 'python{}'.format(self.version), # 'site-packages')) diff --git a/pythonforandroid/recipes/sdl2/__init__.py b/pythonforandroid/recipes/sdl2/__init__.py index fbc88bd6e6..b9d5dfd2b0 100644 --- a/pythonforandroid/recipes/sdl2/__init__.py +++ b/pythonforandroid/recipes/sdl2/__init__.py @@ -18,6 +18,8 @@ def get_recipe_env(self, arch=None): env = super(LibSDL2Recipe, self).get_recipe_env(arch) py2 = self.get_recipe('python2', arch.ctx) env['PYTHON2_NAME'] = py2.get_dir_name() + if 'python2' in self.ctx.recipe_build_order: + env['EXTRA_LDLIBS'] = ' -lpython2.7' return env def build_arch(self, arch): diff --git a/pythonforandroid/tools/liblink b/pythonforandroid/tools/liblink index cf7f26d3bc..0fe2154c84 100755 --- a/pythonforandroid/tools/liblink +++ b/pythonforandroid/tools/liblink @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2.7 from __future__ import print_function import sys @@ -65,6 +65,7 @@ while i < len(sys.argv): f = open(output, "w") f.close() +print('liblink path is', str(environ.get('LIBLINK_PATH'))) output = join(environ.get('LIBLINK_PATH'), basename(output)) f = open(output + ".libs", "w") From 6aa81fdbbf378ab07d493d613bc715c5a641f49e Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 20:43:25 +0000 Subject: [PATCH 21/43] Automatically added python to CythonRecipe depends --- pythonforandroid/recipe.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index ae3f5ad8c6..be697ecc0c 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -809,6 +809,13 @@ class CythonRecipe(PythonRecipe): pre_build_ext = False cythonize = True + def __init__(self, *args, **kwargs): + super(CythonRecipe, self).__init__(*args, **kwargs) + depends = self.depends + depends.append(('python2', 'python3crystax')) + depends = list(set(depends)) + self.depends = depends + def build_arch(self, arch): '''Build any cython components, then install the Python module by calling setup.py install with the target Python dir. From 6af2ae7742e44c0689cb021f1a0a43f74dccf748 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 20:43:58 +0000 Subject: [PATCH 22/43] Made bootstraps use dependency-dependent build dir --- pythonforandroid/bootstrap.py | 21 ++++++++++++++++++++- pythonforandroid/build.py | 1 - pythonforandroid/toolchain.py | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pythonforandroid/bootstrap.py b/pythonforandroid/bootstrap.py index e9c823e606..31c58ca408 100644 --- a/pythonforandroid/bootstrap.py +++ b/pythonforandroid/bootstrap.py @@ -53,8 +53,27 @@ def dist_dir(self): def jni_dir(self): return self.name + self.jni_subdir + def check_recipe_choices(self): + '''Checks what recipes are being built to see which of the alternative + and optional dependencies are being used, + and returns a list of these.''' + recipes = [] + built_recipes = self.ctx.recipe_build_order + for recipe in self.recipe_depends: + if isinstance(recipe, (tuple, list)): + for alternative in recipe: + if alternative in built_recipes: + recipes.append(alternative) + break + return sorted(recipes) + + def get_build_dir_name(self): + choices = self.check_recipe_choices() + dir_name = '-'.join([self.name] + choices) + return dir_name + def get_build_dir(self): - return join(self.ctx.build_dir, 'bootstrap_builds', self.name) + return join(self.ctx.build_dir, 'bootstrap_builds', self.get_build_dir_name()) def get_dist_dir(self, name): return join(self.ctx.dist_dir, name) diff --git a/pythonforandroid/build.py b/pythonforandroid/build.py index 0d9c390004..9081ba2e36 100644 --- a/pythonforandroid/build.py +++ b/pythonforandroid/build.py @@ -518,7 +518,6 @@ def build_recipes(build_order, python_modules, ctx): info_notify( ('The requirements ({}) were not found as recipes, they will be ' 'installed with pip.').format(', '.join(python_modules))) - ctx.recipe_build_order = build_order recipes = [Recipe.get_recipe(name, ctx) for name in build_order] diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py index 983fb451ed..3fee142aa7 100755 --- a/pythonforandroid/toolchain.py +++ b/pythonforandroid/toolchain.py @@ -127,6 +127,7 @@ def build_dist_from_args(ctx, dist, args): bs = Bootstrap.get_bootstrap(args.bootstrap, ctx) build_order, python_modules, bs \ = get_recipe_order_and_bootstrap(ctx, dist.recipes, bs) + ctx.recipe_build_order = build_order info('The selected bootstrap is {}'.format(bs.name)) info_main('# Creating dist with {} bootstrap'.format(bs.name)) From 8784de74624018dd744ff485b1ffd6f0f28ec29c Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 20:44:14 +0000 Subject: [PATCH 23/43] Added python to sdl2 bootstrap depends --- pythonforandroid/bootstraps/sdl2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythonforandroid/bootstraps/sdl2/__init__.py b/pythonforandroid/bootstraps/sdl2/__init__.py index 6816e674de..8cc482cfb6 100644 --- a/pythonforandroid/bootstraps/sdl2/__init__.py +++ b/pythonforandroid/bootstraps/sdl2/__init__.py @@ -7,7 +7,7 @@ class SDL2Bootstrap(Bootstrap): name = 'sdl2' - recipe_depends = ['sdl2'] + recipe_depends = ['sdl2', ('python2', 'python3crystax')] def run_distribute(self): info_main('# Creating Android project from build and {} bootstrap'.format( From a919437979aaa84ba08be5b8ec7ca20e1b2b81c5 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 23:05:57 +0000 Subject: [PATCH 24/43] Modified crystax python include path setting --- pythonforandroid/recipe.py | 36 ++++++++++++------- .../recipes/python3crystax/__init__.py | 6 ---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index be697ecc0c..b5c51fd7d4 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -898,13 +898,15 @@ def get_recipe_env(self, arch): env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format( self.ctx.get_libs_dir(arch.arch) + ' -L{} '.format(self.ctx.libs_dir)) - if self.ctx.ndk_is_crystax: - env['LDFLAGS'] = env['LDFLAGS'] + ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2/libs/armeabi ' - if self.ctx.ndk_is_crystax: + if self.ctx.python_recipe.from_crystax: + env['LDFLAGS'] = (env['LDFLAGS'] + + ' -L{}'.format(join(self.ctx.bootstrap.build_dir, 'libs', arch.arch))) + # ' -L/home/asandy/.local/share/python-for-android/build/bootstrap_builds/sdl2/libs/armeabi ' + if self.ctx.python_recipe.from_crystax: env['LDSHARED'] = env['CC'] + ' -shared' else: env['LDSHARED'] = join(self.ctx.root_dir, 'tools', 'liblink') - shprint(sh.whereis, env['LDSHARED'], _env=env) + # shprint(sh.whereis, env['LDSHARED'], _env=env) env['LIBLINK'] = 'NOTNONE' env['NDKPLATFORM'] = self.ctx.ndk_platform @@ -915,8 +917,8 @@ def get_recipe_env(self, arch): env['LIBLINK_PATH'] = liblink_path ensure_dir(liblink_path) - if self.ctx.ndk_is_crystax: - env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/3.5/include/python ' + env['CFLAGS'] + if self.ctx.python_recipe.from_crystax: + env['CFLAGS'] = '-I/home/asandy/android/crystax-ndk-10.3.0/sources/python/{}/include/python '.format(self.ctx.python_recipe.version) + env['CFLAGS'] return env @@ -933,11 +935,19 @@ def __init__(self, *args, **kwargs): self._ctx = None super(TargetPythonRecipe, self).__init__(*args, **kwargs) - @property - def ctx(self): - return self._ctx + def prebuild_arch(self, arch): + super(TargetPythonRecipe, self).prebuild_arch(arch) + if self.from_crystax and not self.ctx.ndk_is_crystax: + error('The {} recipe can only be built when ' + 'using the CrystaX NDK. Exiting.'.format(self.name)) + exit(1) + self.ctx.python_recipe = self + + # @property + # def ctx(self): + # return self._ctx - @ctx.setter - def ctx(self, ctx): - self._ctx = ctx - ctx.python_recipe = self + # @ctx.setter + # def ctx(self, ctx): + # self._ctx = ctx + # ctx.python_recipe = self diff --git a/pythonforandroid/recipes/python3crystax/__init__.py b/pythonforandroid/recipes/python3crystax/__init__.py index 35531cf77b..d6d96f496c 100644 --- a/pythonforandroid/recipes/python3crystax/__init__.py +++ b/pythonforandroid/recipes/python3crystax/__init__.py @@ -23,12 +23,6 @@ def get_dir_name(self): name += '-version{}'.format(self.version) return name - def prebuild_arch(self, arch): - if not self.ctx.ndk_is_crystax: - error('The python3crystax recipe can only be built when ' - 'using the CrystaX NDK. Exiting.') - exit(1) - def build_arch(self, arch): info('Extracting CrystaX python3 from NDK package') From cecdfc85017127e23d8bc8fdd6e539992224e513 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 23:06:29 +0000 Subject: [PATCH 25/43] Changed Android.mk for sdl2 to work with crystax --- pythonforandroid/archs.py | 4 ++-- pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pythonforandroid/archs.py b/pythonforandroid/archs.py index 61ae3a7583..6ba70be6d0 100644 --- a/pythonforandroid/archs.py +++ b/pythonforandroid/archs.py @@ -102,8 +102,8 @@ def get_env(self): env['ARCH'] = self.arch - if self.ctx.ndk_is_crystax: # AND: should use the right python version from the python recipe - env['CRYSTAX_PYTHON_VERSION'] = '3.5' + if self.ctx.python_recipe.from_crystax: + env['CRYSTAX_PYTHON_VERSION'] = self.ctx.python_recipe.version return env diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk index 743282e2d6..5d2120f2c0 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/Android.mk @@ -16,12 +16,12 @@ LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH) LOCAL_SHARED_LIBRARIES := SDL2 python_shared -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog $(EXTRA_LDLIBS) #-lpython2.7 +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog $(EXTRA_LDLIBS) LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../other_builds/$(PYTHON2_NAME)/$(ARCH)/python2/python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) include $(BUILD_SHARED_LIBRARY) ifdef CRYSTAX_PYTHON_VERSION - $(call import-module,python/$(CRYSTAX_PYTHON_VERSION)) + $(call import-module,python/$(CRYSTAX_PYTHON_VERSION)) endif From 21d7457a3891e17591992f94e8ca4fcacc4373a9 Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 23:06:42 +0000 Subject: [PATCH 26/43] Modified start.c to compile with both py2 and py3 --- .../bootstraps/sdl2/build/jni/src/start.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c index 685d666e57..40ba1ab3b1 100644 --- a/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c +++ b/pythonforandroid/bootstraps/sdl2/build/jni/src/start.c @@ -171,9 +171,9 @@ int main(int argc, char *argv[]) { Py_Initialize(); - if (dir_exists("private/")) { - PySys_SetArgv(argc, argv); - } +#if PY_MAJOR_VERSION < 3 + PySys_SetArgv(argc, argv); +#endif LOG("Initialized python"); @@ -193,8 +193,9 @@ int main(int argc, char *argv[]) { * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); - if (dir_exists("private/")) { + if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly */ + LOG("Setting up python from ANDROID_PRIVATE"); PyRun_SimpleString( "private = posix.environ['ANDROID_PRIVATE']\n" \ "argument = posix.environ['ANDROID_ARGUMENT']\n" \ @@ -204,7 +205,9 @@ int main(int argc, char *argv[]) { " private + '/lib/python2.7/lib-dynload/', \n" \ " private + '/lib/python2.7/site-packages/', \n" \ " argument ]\n"); - } else { + } + + if (dir_exists("crystax_python")) { char add_site_packages_dir[256]; snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", env_argument); From 8f4b996c17d49202c71bcf46013466615ad47fbd Mon Sep 17 00:00:00 2001 From: Alexander Taylor Date: Sat, 9 Jan 2016 23:21:00 +0000 Subject: [PATCH 27/43] Removed unnecessary python3 bootstraps --- .../bootstraps/sdl2python3/__init__.py | 88 - .../sdl2python3/build/AndroidManifest.xml | 45 - .../sdl2python3/build/ant.properties | 17 - .../sdl2python3/build/build.properties | 17 - .../bootstraps/sdl2python3/build/build.py | 340 ---- .../bootstraps/sdl2python3/build/build.xml | 93 - .../sdl2python3/build/jni/Android.mk | 1 - .../sdl2python3/build/jni/Application.mk | 7 - .../sdl2python3/build/jni/src/Android.mk | 23 - .../build/jni/src/Android_static.mk | 12 - .../sdl2python3/build/jni/src/start.c | 218 --- .../sdl2python3/build/jni/src/testgles2.c | 695 -------- .../sdl2python3/build/proguard-project.txt | 20 - .../build/res/drawable-hdpi/ic_launcher.png | Bin 2683 -> 0 bytes .../build/res/drawable-mdpi/ic_launcher.png | Bin 1698 -> 0 bytes .../build/res/drawable-xhdpi/ic_launcher.png | Bin 3872 -> 0 bytes .../build/res/drawable-xxhdpi/ic_launcher.png | Bin 6874 -> 0 bytes .../sdl2python3/build/res/drawable/.gitkeep | 0 .../sdl2python3/build/res/drawable/icon.png | Bin 16525 -> 0 bytes .../sdl2python3/build/res/layout/main.xml | 13 - .../sdl2python3/build/res/values/strings.xml | 5 - .../build/src/org/kamranzafar/jtar/Octal.java | 141 -- .../org/kamranzafar/jtar/TarConstants.java | 28 - .../src/org/kamranzafar/jtar/TarEntry.java | 284 --- .../src/org/kamranzafar/jtar/TarHeader.java | 243 --- .../org/kamranzafar/jtar/TarInputStream.java | 249 --- .../org/kamranzafar/jtar/TarOutputStream.java | 163 -- .../src/org/kamranzafar/jtar/TarUtils.java | 96 - .../src/org/kivy/android/PythonActivity.java | 175 -- .../build/src/org/libsdl/app/SDLActivity.java | 1565 ----------------- .../src/org/renpy/android/AssetExtract.java | 115 -- .../build/src/org/renpy/android/Hardware.java | 287 --- .../org/renpy/android/ResourceManager.java | 54 - .../build/templates/AndroidManifest.xml.tmpl | 53 - .../build/templates/build.xml.tmpl | 93 - .../sdl2python3/build/templates/kivy-icon.png | Bin 16525 -> 0 bytes .../build/templates/strings.xml.tmpl | 5 - .../bootstraps/sdl2python3crystax/__init__.py | 88 - .../build/AndroidManifest.xml | 45 - .../sdl2python3crystax/build/ant.properties | 17 - .../sdl2python3crystax/build/build.properties | 17 - .../sdl2python3crystax/build/build.py | 341 ---- .../sdl2python3crystax/build/build.xml | 93 - .../sdl2python3crystax/build/jni/Android.mk | 1 - .../build/jni/Application.mk | 7 - .../build/proguard-project.txt | 20 - .../build/res/drawable-hdpi/ic_launcher.png | Bin 2683 -> 0 bytes .../build/res/drawable-mdpi/ic_launcher.png | Bin 1698 -> 0 bytes .../build/res/drawable-xhdpi/ic_launcher.png | Bin 3872 -> 0 bytes .../build/res/drawable-xxhdpi/ic_launcher.png | Bin 6874 -> 0 bytes .../build/res/drawable/.gitkeep | 0 .../build/res/drawable/icon.png | Bin 16525 -> 0 bytes .../build/res/layout/main.xml | 13 - .../build/res/values/strings.xml | 5 - .../build/templates/AndroidManifest.xml.tmpl | 53 - .../build/templates/build.xml.tmpl | 93 - .../build/templates/kivy-icon.png | Bin 16525 -> 0 bytes .../build/templates/strings.xml.tmpl | 5 - 58 files changed, 5943 deletions(-) delete mode 100644 pythonforandroid/bootstraps/sdl2python3/__init__.py delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/ant.properties delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/build.properties delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/build.py delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/build.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xhdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable/.gitkeep delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java delete mode 100755 pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/src/org/renpy/android/AssetExtract.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/src/org/renpy/android/Hardware.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/src/org/renpy/android/ResourceManager.java delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/templates/AndroidManifest.xml.tmpl delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/templates/build.xml.tmpl delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/templates/kivy-icon.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3/build/templates/strings.xml.tmpl delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/__init__.py delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/AndroidManifest.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/ant.properties delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/build.properties delete mode 100755 pythonforandroid/bootstraps/sdl2python3crystax/build/build.py delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/build.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Android.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/jni/Application.mk delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/proguard-project.txt delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-hdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-mdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xhdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/.gitkeep delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/drawable/icon.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/layout/main.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/res/values/strings.xml delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/AndroidManifest.xml.tmpl delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/build.xml.tmpl delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/kivy-icon.png delete mode 100644 pythonforandroid/bootstraps/sdl2python3crystax/build/templates/strings.xml.tmpl diff --git a/pythonforandroid/bootstraps/sdl2python3/__init__.py b/pythonforandroid/bootstraps/sdl2python3/__init__.py deleted file mode 100644 index ae693e79eb..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/__init__.py +++ /dev/null @@ -1,88 +0,0 @@ -from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main -from os.path import join, exists -from os import walk -import glob -import sh - -class SDL2Bootstrap(Bootstrap): - name = 'sdl2python3' - - recipe_depends = ['sdl2python3', 'python3'] - - can_be_chosen_automatically = False - - def run_distribute(self): - info_main('# Creating Android project from build and {} bootstrap'.format( - self.name)) - - info('This currently just copies the SDL2 build stuff straight from the build dir.') - shprint(sh.rm, '-rf', self.dist_dir) - shprint(sh.cp, '-r', self.build_dir, self.dist_dir) - with current_directory(self.dist_dir): - with open('local.properties', 'w') as fileh: - fileh.write('sdk.dir={}'.format(self.ctx.sdk_dir)) - - # AND: Hardcoding armeabi - naughty! - arch = ArchARM(self.ctx) - - with current_directory(self.dist_dir): - info('Copying python distribution') - - if not exists('private'): - shprint(sh.mkdir, 'private') - if not exists('assets'): - shprint(sh.mkdir, 'assets') - - hostpython = sh.Command(self.ctx.hostpython) - - # AND: The compileall doesn't work with python3, tries to import a wrong-arch lib - # shprint(hostpython, '-OO', '-m', 'compileall', join(self.ctx.build_dir, 'python-install')) - if not exists('python-install'): - shprint(sh.cp, '-a', join(self.ctx.build_dir, 'python-install'), '.') - - self.distribute_libs(arch, [self.ctx.libs_dir]) - self.distribute_aars(arch) - self.distribute_javaclasses(join(self.ctx.build_dir, 'java')) - - info('Filling private directory') - if not exists(join('private', 'lib')): - info('private/lib does not exist, making') - shprint(sh.cp, '-a', join('python-install', 'lib'), 'private') - shprint(sh.mkdir, '-p', join('private', 'include', 'python3.4m')) - - # AND: Copylibs stuff should go here - if exists(join('libs', 'armeabi', 'libpymodules.so')): - shprint(sh.mv, join('libs', 'armeabi', 'libpymodules.so'), 'private/') - shprint(sh.cp, join('python-install', 'include' , 'python3.4m', 'pyconfig.h'), join('private', 'include', 'python3.4m/')) - - info('Removing some unwanted files') - shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.4m.so')) - shprint(sh.rm, '-f', join('private', 'lib', 'libpython3.so')) - shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig')) - - with current_directory(join(self.dist_dir, 'private', 'lib', 'python3.4')): - # shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.'))) - removes = [] - for dirname, something, filens in walk('.'): - for filename in filens: - for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'): - if filename.endswith(suffix): - removes.append(filename) - shprint(sh.rm, '-f', *removes) - - info('Deleting some other stuff not used on android') - # To quote the original distribute.sh, 'well...' - # shprint(sh.rm, '-rf', 'ctypes') - shprint(sh.rm, '-rf', 'lib2to3') - shprint(sh.rm, '-rf', 'idlelib') - for filename in glob.glob('config/libpython*.a'): - shprint(sh.rm, '-f', filename) - shprint(sh.rm, '-rf', 'config/python.o') - # shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so') - # shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so') - - - self.strip_libraries(arch) - super(SDL2Bootstrap, self).run_distribute() - -bootstrap = SDL2Bootstrap() diff --git a/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml b/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml deleted file mode 100644 index a3dfc7b224..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/AndroidManifest.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/ant.properties b/pythonforandroid/bootstraps/sdl2python3/build/ant.properties deleted file mode 100644 index b0971e891e..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/ant.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# -# This file must be checked into Version Control Systems, as it is -# integral to the build system of your project. - -# This file is only used by the Ant script. - -# You can use this to override default values such as -# 'source.dir' for the location of your java source folder and -# 'out.dir' for the location of your output folder. - -# You can also use it define how the release builds are signed by declaring -# the following properties: -# 'key.store' for the location of your keystore and -# 'key.alias' for the name of the key to use. -# The password will be asked during the build when you use the 'release' target. - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.properties b/pythonforandroid/bootstraps/sdl2python3/build/build.properties deleted file mode 100644 index edc7f23050..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.properties +++ /dev/null @@ -1,17 +0,0 @@ -# This file is used to override default values used by the Ant build system. -# -# This file must be checked in Version Control Systems, as it is -# integral to the build system of your project. - -# This file is only used by the Ant script. - -# You can use this to override default values such as -# 'source.dir' for the location of your java source folder and -# 'out.dir' for the location of your output folder. - -# You can also use it define how the release builds are signed by declaring -# the following properties: -# 'key.store' for the location of your keystore and -# 'key.alias' for the name of the key to use. -# The password will be asked during the build when you use the 'release' target. - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.py b/pythonforandroid/bootstraps/sdl2python3/build/build.py deleted file mode 100755 index 654854049d..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python3 - -from __future__ import print_function - -from os.path import dirname, join, isfile, realpath, relpath, split -import os -import tarfile -import time -import subprocess -import shutil -from zipfile import ZipFile -import sys -import re - -from fnmatch import fnmatch - -import jinja2 - -if os.name == 'nt': - ANDROID = 'android.bat' - ANT = 'ant.bat' -else: - ANDROID = 'android' - ANT = 'ant' - -curdir = dirname(__file__) - -# Try to find a host version of Python that matches our ARM version. -PYTHON = join(curdir, 'python-install', 'bin', 'python.host') - -BLACKLIST_PATTERNS = [ - # code versionning - '^*.hg/*', - '^*.git/*', - '^*.bzr/*', - '^*.svn/*', - - # pyc/py - '*.pyc', - # '*.py', # AND: Need to fix this to add it back - - # temp files - '~', - '*.bak', - '*.swp', -] - -WHITELIST_PATTERNS = [] - -python_files = [] - - -environment = jinja2.Environment(loader=jinja2.FileSystemLoader( - join(curdir, 'templates'))) - -def render(template, dest, **kwargs): - '''Using jinja2, render `template` to the filename `dest`, supplying the - - keyword arguments as template parameters. - ''' - - template = environment.get_template(template) - text = template.render(**kwargs) - - f = open(dest, 'wb') - f.write(text.encode('utf-8')) - f.close() - - -def is_whitelist(name): - return match_filename(WHITELIST_PATTERNS, name) - - -def is_blacklist(name): - if is_whitelist(name): - return False - return match_filename(BLACKLIST_PATTERNS, name) - - -def match_filename(pattern_list, name): - for pattern in pattern_list: - if pattern.startswith('^'): - pattern = pattern[1:] - else: - pattern = '*/' + pattern - if fnmatch(name, pattern): - return True - - -def listfiles(d): - basedir = d - subdirlist = [] - for item in os.listdir(d): - fn = join(d, item) - if isfile(fn): - yield fn - else: - subdirlist.append(os.path.join(basedir, item)) - for subdir in subdirlist: - for fn in listfiles(subdir): - yield fn - -def make_python_zip(): - ''' - Search for all the python related files, and construct the pythonXX.zip - According to - # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html - site-packages, config and lib-dynload will be not included. - ''' - global python_files - d = realpath(join('private', 'lib', 'python3.4')) - - - def select(fn): - if is_blacklist(fn): - return False - fn = realpath(fn) - assert(fn.startswith(d)) - fn = fn[len(d):] - if (fn.startswith('/site-packages/') or - fn.startswith('/config/') or - fn.startswith('/lib-dynload/') or - fn.startswith('/libpymodules.so')): - return False - return fn - - # get a list of all python file - python_files = [x for x in listfiles(d) if select(x)] - - # create the final zipfile - zfn = join('private', 'lib', 'python34.zip') - zf = ZipFile(zfn, 'w') - - # put all the python files in it - for fn in python_files: - afn = fn[len(d):] - zf.write(fn, afn) - zf.close() - -def make_tar(tfn, source_dirs, ignore_path=[]): - ''' - Make a zip file `fn` from the contents of source_dis. - ''' - - # selector function - def select(fn): - rfn = realpath(fn) - for p in ignore_path: - if p.endswith('/'): - p = p[:-1] - if rfn.startswith(p): - return False - if rfn in python_files: - return False - return not is_blacklist(fn) - - # get the files and relpath file of all the directory we asked for - files = [] - for sd in source_dirs: - sd = realpath(sd) - compile_dir(sd) - files += [(x, relpath(realpath(x), sd)) for x in listfiles(sd) - if select(x)] - - # create tar.gz of thoses files - tf = tarfile.open(tfn, 'w:gz', format=tarfile.USTAR_FORMAT) - dirs = [] - for fn, afn in files: - print('%s: %s' % (tfn, fn)) - dn = dirname(afn) - if dn not in dirs: - # create every dirs first if not exist yet - d = '' - for component in split(dn): - d = join(d, component) - if d.startswith('/'): - d = d[1:] - if d == '' or d in dirs: - continue - dirs.append(d) - tinfo = tarfile.TarInfo(d) - tinfo.type = tarfile.DIRTYPE - tf.addfile(tinfo) - - # put the file - tf.add(fn, afn) - tf.close() - - -def compile_dir(dfn): - ''' - Compile *.py in directory `dfn` to *.pyo - ''' - - return # AND: Currently leaving out the compile to pyo step because it's somehow broken - # -OO = strip docstrings - subprocess.call([PYTHON, '-OO', '-m', 'compileall', '-f', dfn]) - - -def make_package(args): - url_scheme = 'kivy' - - # Figure out versions of the private and public data. - private_version = str(time.time()) - - # # Update the project to a recent version. - # try: - # subprocess.call([ANDROID, 'update', 'project', '-p', '.', '-t', - # 'android-{}'.format(args.sdk_version)]) - # except (OSError, IOError): - # print('An error occured while calling', ANDROID, 'update') - # print('Your PATH must include android tools.') - # sys.exit(-1) - - # Delete the old assets. - if os.path.exists('assets/public.mp3'): - os.unlink('assets/public.mp3') - - if os.path.exists('assets/private.mp3'): - os.unlink('assets/private.mp3') - - # In order to speedup import and initial depack, - # construct a python34.zip - make_python_zip() - - # Package up the private and public data. - # AND: Just private for now - if args.private: - make_tar('assets/private.mp3', ['private', args.private], args.ignore_path) - # else: - # make_tar('assets/private.mp3', ['private']) - - # if args.dir: - # make_tar('assets/public.mp3', [args.dir], args.ignore_path) - - - # # Build. - # try: - # for arg in args.command: - # subprocess.check_call([ANT, arg]) - # except (OSError, IOError): - # print 'An error occured while calling', ANT - # print 'Did you install ant on your system ?' - # sys.exit(-1) - - - # Prepare some variables for templating process - - default_icon = 'templates/kivy-icon.png' - shutil.copy(args.icon or default_icon, 'res/drawable/icon.png') - - versioned_name = (args.name.replace(' ', '').replace('\'', '') + - '-' + args.version) - - version_code = 0 - if not args.numeric_version: - for i in args.version.split('.'): - version_code *= 100 - version_code += int(i) - args.numeric_version = str(version_code) - - render( - 'AndroidManifest.xml.tmpl', - 'AndroidManifest.xml', - args=args, - ) - - render( - 'build.xml.tmpl', - 'build.xml', - args=args, - versioned_name=versioned_name) - - render( - 'strings.xml.tmpl', - 'res/values/strings.xml', - args=args) - - with open(join(dirname(__file__), 'res', - 'values', 'strings.xml')) as fileh: - lines = fileh.read() - - with open(join(dirname(__file__), 'res', - 'values', 'strings.xml'), 'w') as fileh: - fileh.write(re.sub(r'"private_version">[0-9\.]*<', - '"private_version">{}<'.format( - str(time.time())), lines)) - - -def parse_args(args=None): - import argparse - ap = argparse.ArgumentParser(description='''\ -Package a Python application for Android. - -For this to work, Java and Ant need to be in your path, as does the -tools directory of the Android SDK. -''') - - ap.add_argument('--private', dest='private', - help='the dir of user files', - required=True) - ap.add_argument('--package', dest='package', - help=('The name of the java package the project will be' - ' packaged under.'), - required=True) - ap.add_argument('--name', dest='name', - help=('The human-readable name of the project.'), - required=True) - ap.add_argument('--numeric-version', dest='numeric_version', - help=('The numeric version number of the project. If not ' - 'given, this is automatically computed from the ' - 'version.')) - ap.add_argument('--version', dest='version', - help=('The version number of the project. This should ' - 'consist of numbers and dots, and should have the ' - 'same number of groups of numbers as previous ' - 'versions.'), - required=True) - ap.add_argument('--orientation', dest='orientation', default='portrait', - help=('The orientation that the game will display in. ' - 'Usually one of "landscape", "portrait" or ' - '"sensor"')) - ap.add_argument('--icon', dest='icon', - help='A png file to use as the icon for the application.') - ap.add_argument('--permission', dest='permissions', action='append', - help='The permissions to give this app.') - - if args is None: - args = sys.argv[1:] - args = ap.parse_args(args) - args.ignore_path = [] - - if args.permissions is None: - args.permissions = [] - - make_package(args) - -if __name__ == "__main__": - - parse_args() diff --git a/pythonforandroid/bootstraps/sdl2python3/build/build.xml b/pythonforandroid/bootstraps/sdl2python3/build/build.xml deleted file mode 100644 index 9f19a077b1..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/build.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk deleted file mode 100644 index 5053e7d643..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk deleted file mode 100644 index e79e378f94..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/Application.mk +++ /dev/null @@ -1,7 +0,0 @@ - -# Uncomment this if you're using STL in your project -# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information -# APP_STL := stlport_static - -# APP_ABI := armeabi armeabi-v7a x86 -APP_ABI := $(ARCH) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk deleted file mode 100644 index 76f0eee24f..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := main - -SDL_PATH := ../SDL - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include - -# Add your application source files here... -LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ - start.c - -LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../python-install/include/python3.4m - -LOCAL_SHARED_LIBRARIES := SDL2 - -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog -lpython3.4m - -LOCAL_LDFLAGS += -L$(LOCAL_PATH)/../../../../python-install/lib $(APPLICATION_ADDITIONAL_LDFLAGS) - -include $(BUILD_SHARED_LIBRARY) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk deleted file mode 100644 index faed669c0e..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/Android_static.mk +++ /dev/null @@ -1,12 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := main - -LOCAL_SRC_FILES := YourSourceHere.c - -LOCAL_STATIC_LIBRARIES := SDL2_static - -include $(BUILD_SHARED_LIBRARY) -$(call import-module,SDL)LOCAL_PATH := $(call my-dir) diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c deleted file mode 100644 index b67bf6894f..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/start.c +++ /dev/null @@ -1,218 +0,0 @@ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#else - -#include -#include -#include -#include - -#include "SDL.h" - -/* #include */ - -#include "android/log.h" - -/* #include "jniwrapperstuff.h" */ - - -/* AND: I don't know why this include is needed! */ -#include "SDL_opengles2.h" - -#define LOG(x) __android_log_write(ANDROID_LOG_INFO, "python", (x)) - -static PyObject *androidembed_log(PyObject *self, PyObject *args) { - char *logstr = NULL; - if (!PyArg_ParseTuple(args, "s", &logstr)) { - return NULL; - } - LOG(logstr); - Py_RETURN_NONE; -} - -static PyMethodDef AndroidEmbedMethods[] = { - {"log", androidembed_log, METH_VARARGS, - "Log on android platform"}, - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef androidembed = - { - PyModuleDef_HEAD_INIT, - "androidembed", - "", - -1, - AndroidEmbedMethods - }; - -PyMODINIT_FUNC initandroidembed(void) { - return PyModule_Create(&androidembed); - /* (void) Py_InitModule("androidembed", AndroidEmbedMethods); */ -} - -int file_exists(const char * filename) -{ - FILE *file; - if (file = fopen(filename, "r")) { - fclose(file); - return 1; - } - return 0; -} - -/* int main(int argc, char **argv) { */ -int main(int argc, char *argv[]) { - - char *env_argument = NULL; - int ret = 0; - FILE *fd; - - /* AND: Several filepaths are hardcoded here, these must be made - configurable */ - /* AND: P4A uses env vars...not sure what's best */ - LOG("Initialize Python for Android"); - /* env_argument = "/data/data/org.kivy.android/files"; */ - env_argument = getenv("ANDROID_ARGUMENT"); - /* setenv("ANDROID_APP_PATH", env_argument, 1); */ - - /* setenv("ANDROID_ARGUMENT", env_argument, 1); */ - /* setenv("ANDROID_PRIVATE", env_argument, 1); */ - /* setenv("ANDROID_APP_PATH", env_argument, 1); */ - /* setenv("PYTHONHOME", env_argument, 1); */ - /* setenv("PYTHONPATH", "/data/data/org.kivy.android/files:/data/data/org.kivy.android/files/lib", 1); */ - - /* LOG("AND: Set env vars"); */ - /* LOG(argv[0]); */ - /* LOG("AND: That was argv 0"); */ - //setenv("PYTHONVERBOSE", "2", 1); - - /* Py_SetProgramName(argv[0]); /\* Disabled due to problem passing wchar_ *\/ */ - Py_SetProgramName("testsetprogramname"); - LOG("Set program name"); - Py_Initialize(); - /* PySys_SetArgv(argc, argv); */ /* Disabled due to problem passing wchar_ */ - - LOG("Initialized python"); - - /* ensure threads will work. - */ - PyEval_InitThreads(); - - LOG("AND: Init threads"); - - /* our logging module for android - */ - initandroidembed(); - - LOG("AND: Init embed"); - - /* inject our bootstrap code to redirect python stdin/stdout - * replace sys.path with our path - */ - PyRun_SimpleString( - "import sys, posix\n" \ - "private = posix.environ['ANDROID_PRIVATE']\n" \ - "argument = posix.environ['ANDROID_ARGUMENT']\n" \ - "sys.path[:] = [ \n" \ - " private + '/lib/python27.zip', \n" \ - " private + '/lib/python2.7/', \n" \ - " private + '/lib/python2.7/lib-dynload/', \n" \ - " private + '/lib/python2.7/site-packages/', \n" \ - " argument ]\n" \ - "import androidembed\n" \ - "class LogFile(object):\n" \ - " def __init__(self):\n" \ - " self.buffer = ''\n" \ - " def write(self, s):\n" \ - " s = self.buffer + s\n" \ - " lines = s.split(\"\\n\")\n" \ - " for l in lines[:-1]:\n" \ - " androidembed.log(l)\n" \ - " self.buffer = lines[-1]\n" \ - " def flush(self):\n" \ - " return\n" \ - "sys.stdout = sys.stderr = LogFile()\n" \ - "import site; print site.getsitepackages()\n"\ - "print 'Android path', sys.path\n" \ - "print 'Android kivy bootstrap done. __name__ is', __name__"); - - LOG("AND: Ran string"); - /* run it ! - */ - LOG("Run user program, change dir and execute main.py"); - chdir(env_argument); - - /* search the initial main.py - */ - char *main_py = "main.pyo"; - if ( file_exists(main_py) == 0 ) { - if ( file_exists("main.py") ) - main_py = "main.py"; - else - main_py = NULL; - } - - if ( main_py == NULL ) { - LOG("No main.pyo / main.py found."); - return -1; - } - - fd = fopen(main_py, "r"); - if ( fd == NULL ) { - LOG("Open the main.py(o) failed"); - return -1; - } - - /* run python ! - */ - ret = PyRun_SimpleFile(fd, main_py); - - if (PyErr_Occurred() != NULL) { - ret = 1; - PyErr_Print(); /* This exits with the right code if SystemExit. */ - PyObject *f = PySys_GetObject("stdout"); - if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ - PyErr_Clear(); - } - - /* close everything - */ - Py_Finalize(); - fclose(fd); - - LOG("Python for android ended."); - return ret; -} - -/* JNIEXPORT void JNICALL JAVA_EXPORT_NAME(PythonService_nativeStart) ( JNIEnv* env, jobject thiz, */ -/* jstring j_android_private, */ -/* jstring j_android_argument, */ -/* jstring j_python_home, */ -/* jstring j_python_path, */ -/* jstring j_arg ) */ -/* { */ -/* jboolean iscopy; */ -/* const char *android_private = (*env)->GetStringUTFChars(env, j_android_private, &iscopy); */ -/* const char *android_argument = (*env)->GetStringUTFChars(env, j_android_argument, &iscopy); */ -/* const char *python_home = (*env)->GetStringUTFChars(env, j_python_home, &iscopy); */ -/* const char *python_path = (*env)->GetStringUTFChars(env, j_python_path, &iscopy); */ -/* const char *arg = (*env)->GetStringUTFChars(env, j_arg, &iscopy); */ - -/* setenv("ANDROID_PRIVATE", android_private, 1); */ -/* setenv("ANDROID_ARGUMENT", android_argument, 1); */ -/* setenv("PYTHONOPTIMIZE", "2", 1); */ -/* setenv("PYTHONHOME", python_home, 1); */ -/* setenv("PYTHONPATH", python_path, 1); */ -/* setenv("PYTHON_SERVICE_ARGUMENT", arg, 1); */ - -/* char *argv[] = { "service" }; */ -/* /\* ANDROID_ARGUMENT points to service subdir, */ -/* * so main() will run main.py from this dir */ -/* *\/ */ -/* main(1, argv); */ -/* } */ - -#endif diff --git a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c b/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c deleted file mode 100644 index ef9f38d607..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/jni/src/testgles2.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - Copyright (r) 1997-2014 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES2 -#endif - -#ifdef HAVE_OPENGLES2 - -#include "SDL_opengles2.h" - -typedef struct GLES2_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC -} GLES2_Context; - - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; -static GLES2_Context ctx; - -static int LoadContext(GLES2_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* _SDL_NOGETPROCADDR_ */ - -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC - return 0; -} - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -#define GL_CHECK(x) \ - x; \ - { \ - GLenum glError = ctx.glGetError(); \ - if(glError != GL_NO_ERROR) { \ - SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ - quit(1); \ - } \ - } - -/* - * Simulates desktop's glRotatef. The matrix is returned in column-major - * order. - */ -static void -rotate_matrix(double angle, double x, double y, double z, float *r) -{ - double radians, c, s, c1, u[3], length; - int i, j; - - radians = (angle * M_PI) / 180.0; - - c = cos(radians); - s = sin(radians); - - c1 = 1.0 - cos(radians); - - length = sqrt(x * x + y * y + z * z); - - u[0] = x / length; - u[1] = y / length; - u[2] = z / length; - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[15] = 1.0; - - for (i = 0; i < 3; i++) { - r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; - r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; - } - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0); - } - } -} - -/* - * Simulates gluPerspectiveMatrix - */ -static void -perspective_matrix(double fovy, double aspect, double znear, double zfar, float *r) -{ - int i; - double f; - - f = 1.0/tan(fovy * 0.5); - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[0] = f / aspect; - r[5] = f; - r[10] = (znear + zfar) / (znear - zfar); - r[11] = -1.0; - r[14] = (2.0 * znear * zfar) / (znear - zfar); - r[15] = 0.0; -} - -/* - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column - * major. In-place multiplication is supported. - */ -static void -multiply_matrix(float *lhs, float *rhs, float *r) -{ - int i, j, k; - float tmp[16]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - tmp[j * 4 + i] = 0.0; - - for (k = 0; k < 4; k++) { - tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; - } - } - } - - for (i = 0; i < 16; i++) { - r[i] = tmp[i]; - } -} - -/* - * Create shader, load in source, compile, dump debug as necessary. - * - * shader: Pointer to return created shader ID. - * source: Passed-in shader source code. - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. - */ -void -process_shader(GLuint *shader, const char * source, GLint shader_type) -{ - GLint status = GL_FALSE; - const char *shaders[1] = { NULL }; - - /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); - - shaders[0] = source; - - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); - - /* Clean up shader source. */ - shaders[0] = NULL; - - /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); - - // Dump debug info (source and log) if compilation failed. - if(status != GL_TRUE) { - SDL_Log("Shader compilation failed"); - quit(-1); - } -} - -/* 3D data. Vertex range -0.5..0.5 in all axes. -* Z -0.5 is near, 0.5 is far. */ -const float _vertices[] = -{ - /* Front face. */ - /* Bottom left */ - -0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top right */ - -0.5, 0.5, -0.5, - 0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - /* Left face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - -0.5, -0.5, -0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, 0.5, 0.5, - -0.5, 0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, -0.5, - /* Top right */ - -0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - /* Right face */ - /* Bottom left */ - 0.5, 0.5, -0.5, - 0.5, -0.5, 0.5, - 0.5, -0.5, -0.5, - /* Top right */ - 0.5, 0.5, -0.5, - 0.5, 0.5, 0.5, - 0.5, -0.5, 0.5, - /* Back face */ - /* Bottom left */ - 0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - 0.5, -0.5, 0.5, - /* Top right */ - 0.5, 0.5, 0.5, - -0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - /* Bottom face */ - /* Bottom left */ - -0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, -}; - -const float _colors[] = -{ - /* Front face */ - /* Bottom left */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 1.0, /* blue */ - 0.0, 1.0, 0.0, /* green */ - /* Top right */ - 1.0, 0.0, 0.0, /* red */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 1.0, /* blue */ - /* Left face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 1.0, 0.0, /* green */ - /* Top face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 0.0, /* red */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 0.0, /* yellow */ - /* Right face */ - /* Bottom left */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - /* Top right */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 0.0, 1.0, /* magenta */ - /* Back face */ - /* Bottom left */ - 0.0, 0.0, 0.0, /* black */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - /* Top right */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - /* Bottom face */ - /* Bottom left */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 0.0, 1.0, /* magenta */ -}; - -const char* _shader_vert_src = -" attribute vec4 av4position; " -" attribute vec3 av3color; " -" uniform mat4 mvp; " -" varying vec3 vv3color; " -" void main() { " -" vv3color = av3color; " -" gl_Position = mvp * av4position; " -" } "; - -const char* _shader_frag_src = -" precision lowp float; " -" varying vec3 vv3color; " -" void main() { " -" gl_FragColor = vec4(vv3color, 1.0); " -" } "; - -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - -} shader_data; - -static void -Render(unsigned int width, unsigned int height, shader_data* data) -{ - float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; - - /* - * Do some rotation with Euler angles. It is not a fixed axis as - * quaterions would be, but the effect is cool. - */ - rotate_matrix(data->angle_x, 1.0, 0.0, 0.0, matrix_modelview); - rotate_matrix(data->angle_y, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - rotate_matrix(data->angle_z, 0.0, 1.0, 0.0, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - /* Pull the camera back from the cube */ - matrix_modelview[14] -= 2.5; - - perspective_matrix(45.0, (double)width/(double)height, 0.01, 100.0, matrix_perspective); - multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); - - data->angle_x += 3; - data->angle_y += 2; - data->angle_z += 1; - - if(data->angle_x >= 360) data->angle_x -= 360; - if(data->angle_x < 0) data->angle_x += 360; - if(data->angle_y >= 360) data->angle_y -= 360; - if(data->angle_y < 0) data->angle_y += 360; - if(data->angle_z >= 360) data->angle_z -= 360; - if(data->angle_z < 0) data->angle_z += 360; - - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - shader_data *datas, *data; - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - SDL_Log ("Usage: %s %s [--fsaa] [--accel] [--zdepth %%d]\n", argv[0], - SDLTest_CommonUsage(state)); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 2; - state->gl_minor_version = 0; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - return 0; - } - - context = SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_Log("Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GLES2 functions\n"); - quit(2); - return 0; - } - - - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - datas = SDL_calloc(state->num_windows, sizeof(shader_data)); - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - ctx.glViewport(0, 0, state->window_w, state->window_h); - - data = &datas[i]; - data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; - - /* Shader Initialization */ - process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); - process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); - - /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); - - /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); - - /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); - - /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); - - GL_CHECK(ctx.glUseProgram(data->shader_program)); - - /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); - - /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event) && !done) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - ctx.glViewport(0, 0, event.window.data1, event.window.data2); - /* Update window content */ - Render(event.window.data1, event.window.data2, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - if (!done) { - for (i = 0; i < state->num_windows; ++i) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(state->window_w, state->window_h, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - } - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES2 */ - -int -main(int argc, char *argv[]) -{ - SDL_Log("No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt b/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt deleted file mode 100644 index f2fe1559a2..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/proguard-project.txt +++ /dev/null @@ -1,20 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index d50bdaae06ee5a8d3f39911f81715abd3bf7b24d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2683 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 diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 0a299eb3cc0273ad1fc260cf0b4a2c35f5d373f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1698 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 diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index d423dac2624cf0b5dc90821a15362bc29e5a1e6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6874 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 diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/.gitkeep b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png b/pythonforandroid/bootstraps/sdl2python3/build/res/drawable/icon.png deleted file mode 100644 index 59a00ba6fff07cec43a4100fdf22f3f679df2349..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16525 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 L>T(q_W}*KFob!<> diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml b/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml deleted file mode 100644 index 123c4b6eac..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/res/layout/main.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml b/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml deleted file mode 100644 index daebceb9d5..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - SDL App - 0.1 - diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java deleted file mode 100755 index dd10624eab..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/Octal.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -/** - * @author Kamran Zafar - * - */ -public class Octal { - - /** - * Parse an octal string from a header buffer. This is used for the file - * permission mode value. - * - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The long value of the octal string. - */ - public static long parseOctal(byte[] header, int offset, int length) { - long result = 0; - boolean stillPadding = true; - - int end = offset + length; - for (int i = offset; i < end; ++i) { - if (header[i] == 0) - break; - - if (header[i] == (byte) ' ' || header[i] == '0') { - if (stillPadding) - continue; - - if (header[i] == (byte) ' ') - break; - } - - stillPadding = false; - - result = ( result << 3 ) + ( header[i] - '0' ); - } - - return result; - } - - /** - * Parse an octal integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The integer value of the octal bytes. - */ - public static int getOctalBytes(long value, byte[] buf, int offset, int length) { - int idx = length - 1; - - buf[offset + idx] = 0; - --idx; - buf[offset + idx] = (byte) ' '; - --idx; - - if (value == 0) { - buf[offset + idx] = (byte) '0'; - --idx; - } else { - for (long val = value; idx >= 0 && val > 0; --idx) { - buf[offset + idx] = (byte) ( (byte) '0' + (byte) ( val & 7 ) ); - val = val >> 3; - } - } - - for (; idx >= 0; --idx) { - buf[offset + idx] = (byte) ' '; - } - - return offset + length; - } - - /** - * Parse the checksum octal integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The integer value of the entry's checksum. - */ - public static int getCheckSumOctalBytes(long value, byte[] buf, int offset, int length) { - getOctalBytes( value, buf, offset, length ); - buf[offset + length - 1] = (byte) ' '; - buf[offset + length - 2] = 0; - return offset + length; - } - - /** - * Parse an octal long integer from a header buffer. - * - * @param value - * @param buf - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * - * @return The long value of the octal bytes. - */ - public static int getLongOctalBytes(long value, byte[] buf, int offset, int length) { - byte[] temp = new byte[length + 1]; - getOctalBytes( value, temp, 0, length + 1 ); - System.arraycopy( temp, 0, buf, offset, length ); - return offset + length; - } - -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java deleted file mode 100755 index 4611e20eaa..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -/** - * @author Kamran Zafar - * - */ -public class TarConstants { - public static final int EOF_BLOCK = 1024; - public static final int DATA_BLOCK = 512; - public static final int HEADER_BLOCK = 512; -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java deleted file mode 100755 index fe01db463a..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarEntry.java +++ /dev/null @@ -1,284 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; -import java.util.Date; - -/** - * @author Kamran Zafar - * - */ -public class TarEntry { - protected File file; - protected TarHeader header; - - private TarEntry() { - this.file = null; - header = new TarHeader(); - } - - public TarEntry(File file, String entryName) { - this(); - this.file = file; - this.extractTarHeader(entryName); - } - - public TarEntry(byte[] headerBuf) { - this(); - this.parseTarHeader(headerBuf); - } - - /** - * Constructor to create an entry from an existing TarHeader object. - * - * This method is useful to add new entries programmatically (e.g. for - * adding files or directories that do not exist in the file system). - * - * @param header - * - */ - public TarEntry(TarHeader header) { - this.file = null; - this.header = header; - } - - public boolean equals(TarEntry it) { - return header.name.toString().equals(it.header.name.toString()); - } - - public boolean isDescendent(TarEntry desc) { - return desc.header.name.toString().startsWith(header.name.toString()); - } - - public TarHeader getHeader() { - return header; - } - - public String getName() { - String name = header.name.toString(); - if (header.namePrefix != null && !header.namePrefix.toString().equals("")) { - name = header.namePrefix.toString() + "/" + name; - } - - return name; - } - - public void setName(String name) { - header.name = new StringBuffer(name); - } - - public int getUserId() { - return header.userId; - } - - public void setUserId(int userId) { - header.userId = userId; - } - - public int getGroupId() { - return header.groupId; - } - - public void setGroupId(int groupId) { - header.groupId = groupId; - } - - public String getUserName() { - return header.userName.toString(); - } - - public void setUserName(String userName) { - header.userName = new StringBuffer(userName); - } - - public String getGroupName() { - return header.groupName.toString(); - } - - public void setGroupName(String groupName) { - header.groupName = new StringBuffer(groupName); - } - - public void setIds(int userId, int groupId) { - this.setUserId(userId); - this.setGroupId(groupId); - } - - public void setModTime(long time) { - header.modTime = time / 1000; - } - - public void setModTime(Date time) { - header.modTime = time.getTime() / 1000; - } - - public Date getModTime() { - return new Date(header.modTime * 1000); - } - - public File getFile() { - return this.file; - } - - public long getSize() { - return header.size; - } - - public void setSize(long size) { - header.size = size; - } - - /** - * Checks if the org.kamrazafar.jtar entry is a directory - * - * @return - */ - public boolean isDirectory() { - if (this.file != null) - return this.file.isDirectory(); - - if (header != null) { - if (header.linkFlag == TarHeader.LF_DIR) - return true; - - if (header.name.toString().endsWith("/")) - return true; - } - - return false; - } - - /** - * Extract header from File - * - * @param entryName - */ - public void extractTarHeader(String entryName) { - header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory()); - } - - /** - * Calculate checksum - * - * @param buf - * @return - */ - public long computeCheckSum(byte[] buf) { - long sum = 0; - - for (int i = 0; i < buf.length; ++i) { - sum += 255 & buf[i]; - } - - return sum; - } - - /** - * Writes the header to the byte buffer - * - * @param outbuf - */ - public void writeEntryHeader(byte[] outbuf) { - int offset = 0; - - offset = TarHeader.getNameBytes(header.name, outbuf, offset, TarHeader.NAMELEN); - offset = Octal.getOctalBytes(header.mode, outbuf, offset, TarHeader.MODELEN); - offset = Octal.getOctalBytes(header.userId, outbuf, offset, TarHeader.UIDLEN); - offset = Octal.getOctalBytes(header.groupId, outbuf, offset, TarHeader.GIDLEN); - - long size = header.size; - - offset = Octal.getLongOctalBytes(size, outbuf, offset, TarHeader.SIZELEN); - offset = Octal.getLongOctalBytes(header.modTime, outbuf, offset, TarHeader.MODTIMELEN); - - int csOffset = offset; - for (int c = 0; c < TarHeader.CHKSUMLEN; ++c) - outbuf[offset++] = (byte) ' '; - - outbuf[offset++] = header.linkFlag; - - offset = TarHeader.getNameBytes(header.linkName, outbuf, offset, TarHeader.NAMELEN); - offset = TarHeader.getNameBytes(header.magic, outbuf, offset, TarHeader.USTAR_MAGICLEN); - offset = TarHeader.getNameBytes(header.userName, outbuf, offset, TarHeader.USTAR_USER_NAMELEN); - offset = TarHeader.getNameBytes(header.groupName, outbuf, offset, TarHeader.USTAR_GROUP_NAMELEN); - offset = Octal.getOctalBytes(header.devMajor, outbuf, offset, TarHeader.USTAR_DEVLEN); - offset = Octal.getOctalBytes(header.devMinor, outbuf, offset, TarHeader.USTAR_DEVLEN); - offset = TarHeader.getNameBytes(header.namePrefix, outbuf, offset, TarHeader.USTAR_FILENAME_PREFIX); - - for (; offset < outbuf.length;) - outbuf[offset++] = 0; - - long checkSum = this.computeCheckSum(outbuf); - - Octal.getCheckSumOctalBytes(checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN); - } - - /** - * Parses the tar header to the byte buffer - * - * @param header - * @param bh - */ - public void parseTarHeader(byte[] bh) { - int offset = 0; - - header.name = TarHeader.parseName(bh, offset, TarHeader.NAMELEN); - offset += TarHeader.NAMELEN; - - header.mode = (int) Octal.parseOctal(bh, offset, TarHeader.MODELEN); - offset += TarHeader.MODELEN; - - header.userId = (int) Octal.parseOctal(bh, offset, TarHeader.UIDLEN); - offset += TarHeader.UIDLEN; - - header.groupId = (int) Octal.parseOctal(bh, offset, TarHeader.GIDLEN); - offset += TarHeader.GIDLEN; - - header.size = Octal.parseOctal(bh, offset, TarHeader.SIZELEN); - offset += TarHeader.SIZELEN; - - header.modTime = Octal.parseOctal(bh, offset, TarHeader.MODTIMELEN); - offset += TarHeader.MODTIMELEN; - - header.checkSum = (int) Octal.parseOctal(bh, offset, TarHeader.CHKSUMLEN); - offset += TarHeader.CHKSUMLEN; - - header.linkFlag = bh[offset++]; - - header.linkName = TarHeader.parseName(bh, offset, TarHeader.NAMELEN); - offset += TarHeader.NAMELEN; - - header.magic = TarHeader.parseName(bh, offset, TarHeader.USTAR_MAGICLEN); - offset += TarHeader.USTAR_MAGICLEN; - - header.userName = TarHeader.parseName(bh, offset, TarHeader.USTAR_USER_NAMELEN); - offset += TarHeader.USTAR_USER_NAMELEN; - - header.groupName = TarHeader.parseName(bh, offset, TarHeader.USTAR_GROUP_NAMELEN); - offset += TarHeader.USTAR_GROUP_NAMELEN; - - header.devMajor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN); - offset += TarHeader.USTAR_DEVLEN; - - header.devMinor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN); - offset += TarHeader.USTAR_DEVLEN; - - header.namePrefix = TarHeader.parseName(bh, offset, TarHeader.USTAR_FILENAME_PREFIX); - } -} \ No newline at end of file diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java deleted file mode 100755 index b9d3a86bef..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarHeader.java +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; - -/** - * Header - * - *
- * Offset  Size     Field
- * 0       100      File name
- * 100     8        File mode
- * 108     8        Owner's numeric user ID
- * 116     8        Group's numeric user ID
- * 124     12       File size in bytes
- * 136     12       Last modification time in numeric Unix time format
- * 148     8        Checksum for header block
- * 156     1        Link indicator (file type)
- * 157     100      Name of linked file
- * 
- * - * - * File Types - * - *
- * Value        Meaning
- * '0'          Normal file
- * (ASCII NUL)  Normal file (now obsolete)
- * '1'          Hard link
- * '2'          Symbolic link
- * '3'          Character special
- * '4'          Block special
- * '5'          Directory
- * '6'          FIFO
- * '7'          Contigous
- * 
- * - * - * - * Ustar header - * - *
- * Offset  Size    Field
- * 257     6       UStar indicator "ustar"
- * 263     2       UStar version "00"
- * 265     32      Owner user name
- * 297     32      Owner group name
- * 329     8       Device major number
- * 337     8       Device minor number
- * 345     155     Filename prefix
- * 
- */ - -public class TarHeader { - - /* - * Header - */ - public static final int NAMELEN = 100; - public static final int MODELEN = 8; - public static final int UIDLEN = 8; - public static final int GIDLEN = 8; - public static final int SIZELEN = 12; - public static final int MODTIMELEN = 12; - public static final int CHKSUMLEN = 8; - public static final byte LF_OLDNORM = 0; - - /* - * File Types - */ - public static final byte LF_NORMAL = (byte) '0'; - public static final byte LF_LINK = (byte) '1'; - public static final byte LF_SYMLINK = (byte) '2'; - public static final byte LF_CHR = (byte) '3'; - public static final byte LF_BLK = (byte) '4'; - public static final byte LF_DIR = (byte) '5'; - public static final byte LF_FIFO = (byte) '6'; - public static final byte LF_CONTIG = (byte) '7'; - - /* - * Ustar header - */ - - public static final String USTAR_MAGIC = "ustar"; // POSIX - - public static final int USTAR_MAGICLEN = 8; - public static final int USTAR_USER_NAMELEN = 32; - public static final int USTAR_GROUP_NAMELEN = 32; - public static final int USTAR_DEVLEN = 8; - public static final int USTAR_FILENAME_PREFIX = 155; - - // Header values - public StringBuffer name; - public int mode; - public int userId; - public int groupId; - public long size; - public long modTime; - public int checkSum; - public byte linkFlag; - public StringBuffer linkName; - public StringBuffer magic; // ustar indicator and version - public StringBuffer userName; - public StringBuffer groupName; - public int devMajor; - public int devMinor; - public StringBuffer namePrefix; - - public TarHeader() { - this.magic = new StringBuffer(TarHeader.USTAR_MAGIC); - - this.name = new StringBuffer(); - this.linkName = new StringBuffer(); - - String user = System.getProperty("user.name", ""); - - if (user.length() > 31) - user = user.substring(0, 31); - - this.userId = 0; - this.groupId = 0; - this.userName = new StringBuffer(user); - this.groupName = new StringBuffer(""); - this.namePrefix = new StringBuffer(); - } - - /** - * Parse an entry name from a header buffer. - * - * @param name - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The header's entry name. - */ - public static StringBuffer parseName(byte[] header, int offset, int length) { - StringBuffer result = new StringBuffer(length); - - int end = offset + length; - for (int i = offset; i < end; ++i) { - if (header[i] == 0) - break; - result.append((char) header[i]); - } - - return result; - } - - /** - * Determine the number of bytes in an entry name. - * - * @param name - * @param header - * The header buffer from which to parse. - * @param offset - * The offset into the buffer from which to parse. - * @param length - * The number of header bytes to parse. - * @return The number of bytes in a header's entry name. - */ - public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) { - int i; - - for (i = 0; i < length && i < name.length(); ++i) { - buf[offset + i] = (byte) name.charAt(i); - } - - for (; i < length; ++i) { - buf[offset + i] = 0; - } - - return offset + length; - } - - /** - * Creates a new header for a file/directory entry. - * - * - * @param name - * File name - * @param size - * File size in bytes - * @param modTime - * Last modification time in numeric Unix time format - * @param dir - * Is directory - * - * @return - */ - public static TarHeader createHeader(String entryName, long size, long modTime, boolean dir) { - String name = entryName; - name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/'); - - TarHeader header = new TarHeader(); - header.linkName = new StringBuffer(""); - - if (name.length() > 100) { - header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/'))); - header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1)); - } else { - header.name = new StringBuffer(name); - } - - if (dir) { - header.mode = 040755; - header.linkFlag = TarHeader.LF_DIR; - if (header.name.charAt(header.name.length() - 1) != '/') { - header.name.append("/"); - } - header.size = 0; - } else { - header.mode = 0100644; - header.linkFlag = TarHeader.LF_NORMAL; - header.size = size; - } - - header.modTime = modTime; - header.checkSum = 0; - header.devMajor = 0; - header.devMinor = 0; - - return header; - } -} \ No newline at end of file diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java deleted file mode 100755 index ec50a1b688..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarInputStream.java +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Kamran Zafar - * - */ -public class TarInputStream extends FilterInputStream { - - private static final int SKIP_BUFFER_SIZE = 2048; - private TarEntry currentEntry; - private long currentFileSize; - private long bytesRead; - private boolean defaultSkip = false; - - public TarInputStream(InputStream in) { - super(in); - currentFileSize = 0; - bytesRead = 0; - } - - @Override - public boolean markSupported() { - return false; - } - - /** - * Not supported - * - */ - @Override - public synchronized void mark(int readlimit) { - } - - /** - * Not supported - * - */ - @Override - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } - - /** - * Read a byte - * - * @see java.io.FilterInputStream#read() - */ - @Override - public int read() throws IOException { - byte[] buf = new byte[1]; - - int res = this.read(buf, 0, 1); - - if (res != -1) { - return 0xFF & buf[0]; - } - - return res; - } - - /** - * Checks if the bytes being read exceed the entry size and adjusts the byte - * array length. Updates the byte counters - * - * - * @see java.io.FilterInputStream#read(byte[], int, int) - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (currentEntry != null) { - if (currentFileSize == currentEntry.getSize()) { - return -1; - } else if ((currentEntry.getSize() - currentFileSize) < len) { - len = (int) (currentEntry.getSize() - currentFileSize); - } - } - - int br = super.read(b, off, len); - - if (br != -1) { - if (currentEntry != null) { - currentFileSize += br; - } - - bytesRead += br; - } - - return br; - } - - /** - * Returns the next entry in the tar file - * - * @return TarEntry - * @throws IOException - */ - public TarEntry getNextEntry() throws IOException { - closeCurrentEntry(); - - byte[] header = new byte[TarConstants.HEADER_BLOCK]; - byte[] theader = new byte[TarConstants.HEADER_BLOCK]; - int tr = 0; - - // Read full header - while (tr < TarConstants.HEADER_BLOCK) { - int res = read(theader, 0, TarConstants.HEADER_BLOCK - tr); - - if (res < 0) { - break; - } - - System.arraycopy(theader, 0, header, tr, res); - tr += res; - } - - // Check if record is null - boolean eof = true; - for (byte b : header) { - if (b != 0) { - eof = false; - break; - } - } - - if (!eof) { - currentEntry = new TarEntry(header); - } - - return currentEntry; - } - - /** - * Returns the current offset (in bytes) from the beginning of the stream. - * This can be used to find out at which point in a tar file an entry's content begins, for instance. - */ - public long getCurrentOffset() { - return bytesRead; - } - - /** - * Closes the current tar entry - * - * @throws IOException - */ - protected void closeCurrentEntry() throws IOException { - if (currentEntry != null) { - if (currentEntry.getSize() > currentFileSize) { - // Not fully read, skip rest of the bytes - long bs = 0; - while (bs < currentEntry.getSize() - currentFileSize) { - long res = skip(currentEntry.getSize() - currentFileSize - bs); - - if (res == 0 && currentEntry.getSize() - currentFileSize > 0) { - // I suspect file corruption - throw new IOException("Possible tar file corruption"); - } - - bs += res; - } - } - - currentEntry = null; - currentFileSize = 0L; - skipPad(); - } - } - - /** - * Skips the pad at the end of each tar entry file content - * - * @throws IOException - */ - protected void skipPad() throws IOException { - if (bytesRead > 0) { - int extra = (int) (bytesRead % TarConstants.DATA_BLOCK); - - if (extra > 0) { - long bs = 0; - while (bs < TarConstants.DATA_BLOCK - extra) { - long res = skip(TarConstants.DATA_BLOCK - extra - bs); - bs += res; - } - } - } - } - - /** - * Skips 'n' bytes on the InputStream
- * Overrides default implementation of skip - * - */ - @Override - public long skip(long n) throws IOException { - if (defaultSkip) { - // use skip method of parent stream - // may not work if skip not implemented by parent - long bs = super.skip(n); - bytesRead += bs; - - return bs; - } - - if (n <= 0) { - return 0; - } - - long left = n; - byte[] sBuff = new byte[SKIP_BUFFER_SIZE]; - - while (left > 0) { - int res = read(sBuff, 0, (int) (left < SKIP_BUFFER_SIZE ? left : SKIP_BUFFER_SIZE)); - if (res < 0) { - break; - } - left -= res; - } - - return n - left; - } - - public boolean isDefaultSkip() { - return defaultSkip; - } - - public void setDefaultSkip(boolean defaultSkip) { - this.defaultSkip = defaultSkip; - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java deleted file mode 100755 index ffdfe87564..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarOutputStream.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; - -/** - * @author Kamran Zafar - * - */ -public class TarOutputStream extends OutputStream { - private final OutputStream out; - private long bytesWritten; - private long currentFileSize; - private TarEntry currentEntry; - - public TarOutputStream(OutputStream out) { - this.out = out; - bytesWritten = 0; - currentFileSize = 0; - } - - public TarOutputStream(final File fout) throws FileNotFoundException { - this.out = new BufferedOutputStream(new FileOutputStream(fout)); - bytesWritten = 0; - currentFileSize = 0; - } - - /** - * Opens a file for writing. - */ - public TarOutputStream(final File fout, final boolean append) throws IOException { - @SuppressWarnings("resource") - RandomAccessFile raf = new RandomAccessFile(fout, "rw"); - final long fileSize = fout.length(); - if (append && fileSize > TarConstants.EOF_BLOCK) { - raf.seek(fileSize - TarConstants.EOF_BLOCK); - } - out = new BufferedOutputStream(new FileOutputStream(raf.getFD())); - } - - /** - * Appends the EOF record and closes the stream - * - * @see java.io.FilterOutputStream#close() - */ - @Override - public void close() throws IOException { - closeCurrentEntry(); - write( new byte[TarConstants.EOF_BLOCK] ); - out.close(); - } - /** - * Writes a byte to the stream and updates byte counters - * - * @see java.io.FilterOutputStream#write(int) - */ - @Override - public void write(int b) throws IOException { - out.write( b ); - bytesWritten += 1; - - if (currentEntry != null) { - currentFileSize += 1; - } - } - - /** - * Checks if the bytes being written exceed the current entry size. - * - * @see java.io.FilterOutputStream#write(byte[], int, int) - */ - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (currentEntry != null && !currentEntry.isDirectory()) { - if (currentEntry.getSize() < currentFileSize + len) { - throw new IOException( "The current entry[" + currentEntry.getName() + "] size[" - + currentEntry.getSize() + "] is smaller than the bytes[" + ( currentFileSize + len ) - + "] being written." ); - } - } - - out.write( b, off, len ); - - bytesWritten += len; - - if (currentEntry != null) { - currentFileSize += len; - } - } - - /** - * Writes the next tar entry header on the stream - * - * @param entry - * @throws IOException - */ - public void putNextEntry(TarEntry entry) throws IOException { - closeCurrentEntry(); - - byte[] header = new byte[TarConstants.HEADER_BLOCK]; - entry.writeEntryHeader( header ); - - write( header ); - - currentEntry = entry; - } - - /** - * Closes the current tar entry - * - * @throws IOException - */ - protected void closeCurrentEntry() throws IOException { - if (currentEntry != null) { - if (currentEntry.getSize() > currentFileSize) { - throw new IOException( "The current entry[" + currentEntry.getName() + "] of size[" - + currentEntry.getSize() + "] has not been fully written." ); - } - - currentEntry = null; - currentFileSize = 0; - - pad(); - } - } - - /** - * Pads the last content block - * - * @throws IOException - */ - protected void pad() throws IOException { - if (bytesWritten > 0) { - int extra = (int) ( bytesWritten % TarConstants.DATA_BLOCK ); - - if (extra > 0) { - write( new byte[TarConstants.DATA_BLOCK - extra] ); - } - } - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java deleted file mode 100755 index 50165765c0..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kamranzafar/jtar/TarUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright 2012 Kamran Zafar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.kamranzafar.jtar; - -import java.io.File; - -/** - * @author Kamran - * - */ -public class TarUtils { - /** - * Determines the tar file size of the given folder/file path - * - * @param path - * @return - */ - public static long calculateTarSize(File path) { - return tarSize(path) + TarConstants.EOF_BLOCK; - } - - private static long tarSize(File dir) { - long size = 0; - - if (dir.isFile()) { - return entrySize(dir.length()); - } else { - File[] subFiles = dir.listFiles(); - - if (subFiles != null && subFiles.length > 0) { - for (File file : subFiles) { - if (file.isFile()) { - size += entrySize(file.length()); - } else { - size += tarSize(file); - } - } - } else { - // Empty folder header - return TarConstants.HEADER_BLOCK; - } - } - - return size; - } - - private static long entrySize(long fileSize) { - long size = 0; - size += TarConstants.HEADER_BLOCK; // Header - size += fileSize; // File size - - long extra = size % TarConstants.DATA_BLOCK; - - if (extra > 0) { - size += (TarConstants.DATA_BLOCK - extra); // pad - } - - return size; - } - - public static String trim(String s, char c) { - StringBuffer tmp = new StringBuffer(s); - for (int i = 0; i < tmp.length(); i++) { - if (tmp.charAt(i) != c) { - break; - } else { - tmp.deleteCharAt(i); - } - } - - for (int i = tmp.length() - 1; i >= 0; i--) { - if (tmp.charAt(i) != c) { - break; - } else { - tmp.deleteCharAt(i); - } - } - - return tmp.toString(); - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java deleted file mode 100644 index 7c6a478275..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/kivy/android/PythonActivity.java +++ /dev/null @@ -1,175 +0,0 @@ - -package org.kivy.android; - -import java.io.InputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.File; - -import android.app.Activity; -import android.util.Log; -import android.widget.Toast; -import android.os.Bundle; - -import org.libsdl.app.SDLActivity; - -import org.renpy.android.ResourceManager; -import org.renpy.android.AssetExtract; - -public class PythonActivity extends SDLActivity { - private static final String TAG = "PythonActivity"; - - public static PythonActivity mActivity = null; - - private ResourceManager resourceManager; - - @Override - protected void onCreate(Bundle savedInstanceState) { - Log.v(TAG, "My oncreate running"); - resourceManager = new ResourceManager(this); - - Log.v(TAG, "Ready to unpack"); - unpackData("private", getFilesDir()); - - Log.v(TAG, "About to do super onCreate"); - super.onCreate(savedInstanceState); - Log.v(TAG, "Did super onCreate"); - - this.mActivity = this; - - String mFilesDirectory = mActivity.getFilesDir().getAbsolutePath(); - Log.v(TAG, "Setting env vars for start.c and Python to use"); - SDLActivity.nativeSetEnv("ANDROID_PRIVATE", mFilesDirectory); - SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", mFilesDirectory); - SDLActivity.nativeSetEnv("ANDROID_APP_PATH", mFilesDirectory); - SDLActivity.nativeSetEnv("PYTHONHOME", mFilesDirectory); - SDLActivity.nativeSetEnv("", mFilesDirectory + ":" + mFilesDirectory + "/lib"); - - - // nativeSetEnv("ANDROID_ARGUMENT", getFilesDir()); - } - - // This is just overrides the normal SDLActivity, which just loads - // SDL2 and main - protected String[] getLibraries() { - return new String[] { - "SDL2", - "SDL2_image", - "SDL2_mixer", - "SDL2_ttf", - "python3.4m", - "python3", - "main" - }; - } - - public void loadLibraries() { - // AND: This should probably be replaced by a call to super - for (String lib : getLibraries()) { - System.loadLibrary(lib); - } - - // System.load(getFilesDir() + "/lib/python3.4/lib-dynload/_io.so"); - System.load(getFilesDir() + "/lib/python3.4/lib-dynload/unicodedata.cpython-34m.so"); - - try { - // System.loadLibrary("ctypes"); - System.load(getFilesDir() + "/lib/python3.4/lib-dynload/_ctypes.cpython-34m.so"); - } catch(UnsatisfiedLinkError e) { - Log.v(TAG, "Unsatisfied linker when loading ctypes"); - } - - Log.v(TAG, "Loaded everything!"); - } - - public void recursiveDelete(File f) { - if (f.isDirectory()) { - for (File r : f.listFiles()) { - recursiveDelete(r); - } - } - f.delete(); - } - - /** - * Show an error using a toast. (Only makes sense from non-UI - * threads.) - */ - public void toastError(final String msg) { - - final Activity thisActivity = this; - - runOnUiThread(new Runnable () { - public void run() { - Toast.makeText(thisActivity, msg, Toast.LENGTH_LONG).show(); - } - }); - - // Wait to show the error. - synchronized (this) { - try { - this.wait(1000); - } catch (InterruptedException e) { - } - } - } - - public void unpackData(final String resource, File target) { - - Log.v(TAG, "UNPACKING!!! " + resource + " " + target.getName()); - - // The version of data in memory and on disk. - String data_version = resourceManager.getString(resource + "_version"); - String disk_version = null; - - Log.v(TAG, "Data version is " + data_version); - - // If no version, no unpacking is necessary. - if (data_version == null) { - return; - } - - // Check the current disk version, if any. - String filesDir = target.getAbsolutePath(); - String disk_version_fn = filesDir + "/" + resource + ".version"; - - try { - byte buf[] = new byte[64]; - InputStream is = new FileInputStream(disk_version_fn); - int len = is.read(buf); - disk_version = new String(buf, 0, len); - is.close(); - } catch (Exception e) { - disk_version = ""; - } - - // If the disk data is out of date, extract it and write the - // version file. - // if (! data_version.equals(disk_version)) { - if (! data_version.equals(disk_version)) { - Log.v(TAG, "Extracting " + resource + " assets."); - - recursiveDelete(target); - target.mkdirs(); - - AssetExtract ae = new AssetExtract(this); - if (!ae.extractTar(resource + ".mp3", target.getAbsolutePath())) { - toastError("Could not extract " + resource + " data."); - } - - try { - // Write .nomedia. - new File(target, ".nomedia").createNewFile(); - - // Write version file. - FileOutputStream os = new FileOutputStream(disk_version_fn); - os.write(data_version.getBytes()); - os.close(); - } catch (Exception e) { - Log.w("python", e); - } - } - - } -} diff --git a/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java b/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java deleted file mode 100644 index 76134e8274..0000000000 --- a/pythonforandroid/bootstraps/sdl2python3/build/src/org/libsdl/app/SDLActivity.java +++ /dev/null @@ -1,1565 +0,0 @@ -package org.libsdl.app; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.lang.reflect.Method; - -import android.app.*; -import android.content.*; -import android.view.*; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.widget.AbsoluteLayout; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.os.*; -import android.util.Log; -import android.util.SparseArray; -import android.graphics.*; -import android.graphics.drawable.Drawable; -import android.media.*; -import android.hardware.*; - -/** - SDL Activity -*/ -public class SDLActivity extends Activity { - private static final String TAG = "SDL"; - - // Keep track of the paused state - public static boolean mIsPaused, mIsSurfaceReady, mHasFocus; - public static boolean mExitCalledFromJava; - - /** If shared libraries (e.g. SDL or the native application) could not be loaded. */ - public static boolean mBrokenLibraries; - - // If we want to separate mouse and touch events. - // This is only toggled in native code when a hint is set! - public static boolean mSeparateMouseAndTouch; - - // Main components - protected static SDLActivity mSingleton; - protected static SDLSurface mSurface; - protected static View mTextEdit; - protected static ViewGroup mLayout; - protected static SDLJoystickHandler mJoystickHandler; - - // This is what SDL runs in. It invokes SDL_main(), eventually - protected static Thread mSDLThread; - - // Audio - protected static AudioTrack mAudioTrack; - - /** - * This method is called by SDL before loading the native shared libraries. - * It can be overridden to provide names of shared libraries to be loaded. - * The default implementation returns the defaults. It never returns null. - * An array returned by a new implementation must at least contain "SDL2". - * Also keep in mind that the order the libraries are loaded may matter. - * @return names of shared libraries to be loaded (e.g. "SDL2", "main"). - */ - protected String[] getLibraries() { - return new String[] { - "SDL2", - // "SDL2_image", - // "SDL2_mixer", - // "SDL2_net", - // "SDL2_ttf", - "main" - }; - } - - // Load the .so - public void loadLibraries() { - for (String lib : getLibraries()) { - System.loadLibrary(lib); - } - } - - /** - * This method is called by SDL before starting the native application thread. - * It can be overridden to provide the arguments after the application name. - * The default implementation returns an empty array. It never returns null. - * @return arguments for the native application. - */ - protected String[] getArguments() { - return new String[0]; - } - - public static void initialize() { - // The static nature of the singleton and Android quirkyness force us to initialize everything here - // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values - mSingleton = null; - mSurface = null; - mTextEdit = null; - mLayout = null; - mJoystickHandler = null; - mSDLThread = null; - mAudioTrack = null; - mExitCalledFromJava = false; - mBrokenLibraries = false; - mIsPaused = false; - mIsSurfaceReady = false; - mHasFocus = true; - } - - // Setup - @Override - protected void onCreate(Bundle savedInstanceState) { - Log.v("SDL", "Device: " + android.os.Build.DEVICE); - Log.v("SDL", "Model: " + android.os.Build.MODEL); - Log.v("SDL", "onCreate():" + mSingleton); - super.onCreate(savedInstanceState); - - SDLActivity.initialize(); - // So we can call stuff from static callbacks - mSingleton = this; - - // Load shared libraries - String errorMsgBrokenLib = ""; - try { - loadLibraries(); - } catch(UnsatisfiedLinkError e) { - System.err.println(e.getMessage()); - mBrokenLibraries = true; - errorMsgBrokenLib = e.getMessage(); - } catch(Exception e) { - System.err.println(e.getMessage()); - mBrokenLibraries = true; - errorMsgBrokenLib = e.getMessage(); - } - - if (mBrokenLibraries) - { - AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); - dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall." - + System.getProperty("line.separator") - + System.getProperty("line.separator") - + "Error: " + errorMsgBrokenLib); - dlgAlert.setTitle("SDL Error"); - dlgAlert.setPositiveButton("Exit", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog,int id) { - // if this button is clicked, close current activity - SDLActivity.mSingleton.finish(); - } - }); - dlgAlert.setCancelable(false); - dlgAlert.create().show(); - - return; - } - - // Set up the surface - mSurface = new SDLSurface(getApplication()); - - if(Build.VERSION.SDK_INT >= 12) { - mJoystickHandler = new SDLJoystickHandler_API12(); - } - else { - mJoystickHandler = new SDLJoystickHandler(); - } - - mLayout = new AbsoluteLayout(this); - mLayout.addView(mSurface); - - setContentView(mLayout); - } - - // Events - @Override - protected void onPause() { - Log.v("SDL", "onPause()"); - super.onPause(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.handlePause(); - } - - @Override - protected void onResume() { - Log.v("SDL", "onResume()"); - super.onResume(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.handleResume(); - } - - - @Override - public void onWindowFocusChanged(boolean hasFocus) { - super.onWindowFocusChanged(hasFocus); - Log.v("SDL", "onWindowFocusChanged(): " + hasFocus); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.mHasFocus = hasFocus; - if (hasFocus) { - SDLActivity.handleResume(); - } - } - - @Override - public void onLowMemory() { - Log.v("SDL", "onLowMemory()"); - super.onLowMemory(); - - if (SDLActivity.mBrokenLibraries) { - return; - } - - SDLActivity.nativeLowMemory(); - } - - @Override - protected void onDestroy() { - Log.v("SDL", "onDestroy()"); - - if (SDLActivity.mBrokenLibraries) { - super.onDestroy(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); - return; - } - - // Send a quit message to the application - SDLActivity.mExitCalledFromJava = true; - SDLActivity.nativeQuit(); - - // Now wait for the SDL thread to quit - if (SDLActivity.mSDLThread != null) { - try { - SDLActivity.mSDLThread.join(); - } catch(Exception e) { - Log.v("SDL", "Problem stopping thread: " + e); - } - SDLActivity.mSDLThread = null; - - //Log.v("SDL", "Finished waiting for SDL thread"); - } - - super.onDestroy(); - // Reset everything in case the user re opens the app - SDLActivity.initialize(); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - - if (SDLActivity.mBrokenLibraries) { - return false; - } - - int keyCode = event.getKeyCode(); - // Ignore certain special keys so they're handled by Android - if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || - keyCode == KeyEvent.KEYCODE_VOLUME_UP || - keyCode == KeyEvent.KEYCODE_CAMERA || - keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */ - keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */ - ) { - return false; - } - return super.dispatchKeyEvent(event); - } - - /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed - * is the first to be called, mIsSurfaceReady should still be set - * to 'true' during the call to onPause (in a usual scenario). - */ - public static void handlePause() { - if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) { - SDLActivity.mIsPaused = true; - SDLActivity.nativePause(); - mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false); - } - } - - /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready. - * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume - * every time we get one of those events, only if it comes after surfaceDestroyed - */ - public static void handleResume() { - if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) { - SDLActivity.mIsPaused = false; - SDLActivity.nativeResume(); - mSurface.handleResume(); - } - } - - /* The native thread has finished */ - public static void handleNativeExit() { - SDLActivity.mSDLThread = null; - mSingleton.finish(); - } - - - // Messages from the SDLMain thread - static final int COMMAND_CHANGE_TITLE = 1; - static final int COMMAND_UNUSED = 2; - static final int COMMAND_TEXTEDIT_HIDE = 3; - static final int COMMAND_SET_KEEP_SCREEN_ON = 5; - - protected static final int COMMAND_USER = 0x8000; - - /** - * This method is called by SDL if SDL did not handle a message itself. - * This happens if a received message contains an unsupported command. - * Method can be overwritten to handle Messages in a different class. - * @param command the command of the message. - * @param param the parameter of the message. May be null. - * @return if the message was handled in overridden method. - */ - protected boolean onUnhandledMessage(int command, Object param) { - return false; - } - - /** - * A Handler class for Messages from native SDL applications. - * It uses current Activities as target (e.g. for the title). - * static to prevent implicit references to enclosing object. - */ - protected static class SDLCommandHandler extends Handler { - @Override - public void handleMessage(Message msg) { - Context context = getContext(); - if (context == null) { - Log.e(TAG, "error handling message, getContext() returned null"); - return; - } - switch (msg.arg1) { - case COMMAND_CHANGE_TITLE: - if (context instanceof Activity) { - ((Activity) context).setTitle((String)msg.obj); - } else { - Log.e(TAG, "error handling message, getContext() returned no Activity"); - } - break; - case COMMAND_TEXTEDIT_HIDE: - if (mTextEdit != null) { - mTextEdit.setVisibility(View.GONE); - - InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); - } - break; - case COMMAND_SET_KEEP_SCREEN_ON: - { - Window window = ((Activity) context).getWindow(); - if (window != null) { - if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } else { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - } - break; - } - default: - if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) { - Log.e(TAG, "error handling message, command is " + msg.arg1); - } - } - } - } - - // Handler for the messages - Handler commandHandler = new SDLCommandHandler(); - - // Send a message from the SDLMain thread - boolean sendCommand(int command, Object data) { - Message msg = commandHandler.obtainMessage(); - msg.arg1 = command; - msg.obj = data; - return commandHandler.sendMessage(msg); - } - - // C functions we call - public static native int nativeInit(Object arguments); - public static native void nativeLowMemory(); - public static native void nativeQuit(); - public static native void nativePause(); - public static native void nativeResume(); - public static native void onNativeResize(int x, int y, int format, float rate); - public static native int onNativePadDown(int device_id, int keycode); - public static native int onNativePadUp(int device_id, int keycode); - public static native void onNativeJoy(int device_id, int axis, - float value); - public static native void onNativeHat(int device_id, int hat_id, - int x, int y); - public static native void nativeSetEnv(String j_name, String j_value); - public static native void onNativeKeyDown(int keycode); - public static native void onNativeKeyUp(int keycode); - public static native void onNativeKeyboardFocusLost(); - public static native void onNativeMouse(int button, int action, float x, float y); - public static native void onNativeTouch(int touchDevId, int pointerFingerId, - int action, float x, - float y, float p); - public static native void onNativeAccel(float x, float y, float z); - public static native void onNativeSurfaceChanged(); - public static native void onNativeSurfaceDestroyed(); - public static native void nativeFlipBuffers(); - public static native int nativeAddJoystick(int device_id, String name, - int is_accelerometer, int nbuttons, - int naxes, int nhats, int nballs); - public static native int nativeRemoveJoystick(int device_id); - public static native String nativeGetHint(String name); - - /** - * This method is called by SDL using JNI. - */ - public static void flipBuffers() { - SDLActivity.nativeFlipBuffers(); - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean setActivityTitle(String title) { - // Called from SDLMain() thread and can't directly affect the view - return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title); - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean sendMessage(int command, int param) { - return mSingleton.sendCommand(command, Integer.valueOf(param)); - } - - /** - * This method is called by SDL using JNI. - */ - public static Context getContext() { - return mSingleton; - } - - /** - * This method is called by SDL using JNI. - * @return result of getSystemService(name) but executed on UI thread. - */ - public Object getSystemServiceFromUiThread(final String name) { - final Object lock = new Object(); - final Object[] results = new Object[2]; // array for writable variables - synchronized (lock) { - runOnUiThread(new Runnable() { - @Override - public void run() { - synchronized (lock) { - results[0] = getSystemService(name); - results[1] = Boolean.TRUE; - lock.notify(); - } - } - }); - if (results[1] == null) { - try { - lock.wait(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - } - return results[0]; - } - - static class ShowTextInputTask implements Runnable { - /* - * This is used to regulate the pan&scan method to have some offset from - * the bottom edge of the input region and the top edge of an input - * method (soft keyboard) - */ - static final int HEIGHT_PADDING = 15; - - public int x, y, w, h; - - public ShowTextInputTask(int x, int y, int w, int h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - @Override - public void run() { - AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams( - w, h + HEIGHT_PADDING, x, y); - - if (mTextEdit == null) { - mTextEdit = new DummyEdit(getContext()); - - mLayout.addView(mTextEdit, params); - } else { - mTextEdit.setLayoutParams(params); - } - - mTextEdit.setVisibility(View.VISIBLE); - mTextEdit.requestFocus(); - - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mTextEdit, 0); - } - } - - /** - * This method is called by SDL using JNI. - */ - public static boolean showTextInput(int x, int y, int w, int h) { - // Transfer the task to the main thread as a Runnable - return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h)); - } - - /** - * This method is called by SDL using JNI. - */ - public static Surface getNativeSurface() { - return SDLActivity.mSurface.getNativeSurface(); - } - - // Audio - - /** - * This method is called by SDL using JNI. - */ - public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - - Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); - - if (mAudioTrack == null) { - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); - - // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid - // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java - // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState() - - if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) { - Log.e("SDL", "Failed during initialization of Audio Track"); - mAudioTrack = null; - return -1; - } - - mAudioTrack.play(); - } - - Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - return 0; - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteShortBuffer(short[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(short)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteByteBuffer(byte[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w("SDL", "SDL audio: error return from write(byte)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioQuit() { - if (mAudioTrack != null) { - mAudioTrack.stop(); - mAudioTrack = null; - } - } - - // Input - - /** - * This method is called by SDL using JNI. - * @return an array which may be empty but is never null. - */ - public static int[] inputGetInputDeviceIds(int sources) { - int[] ids = InputDevice.getDeviceIds(); - int[] filtered = new int[ids.length]; - int used = 0; - for (int i = 0; i < ids.length; ++i) { - InputDevice device = InputDevice.getDevice(ids[i]); - if ((device != null) && ((device.getSources() & sources) != 0)) { - filtered[used++] = device.getId(); - } - } - return Arrays.copyOf(filtered, used); - } - - // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance - public static boolean handleJoystickMotionEvent(MotionEvent event) { - return mJoystickHandler.handleMotionEvent(event); - } - - /** - * This method is called by SDL using JNI. - */ - public static void pollInputDevices() { - if (SDLActivity.mSDLThread != null) { - mJoystickHandler.pollInputDevices(); - } - } - - // APK extension files support - - /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */ - private Object expansionFile; - - /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */ - private Method expansionFileMethod; - - /** - * This method is called by SDL using JNI. - */ - public InputStream openAPKExtensionInputStream(String fileName) throws IOException { - // Get a ZipResourceFile representing a merger of both the main and patch files - if (expansionFile == null) { - Integer mainVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION")); - Integer patchVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION")); - - try { - // To avoid direct dependency on Google APK extension library that is - // not a part of Android SDK we access it using reflection - expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport") - .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class) - .invoke(null, this, mainVersion, patchVersion); - - expansionFileMethod = expansionFile.getClass() - .getMethod("getInputStream", String.class); - } catch (Exception ex) { - ex.printStackTrace(); - expansionFile = null; - expansionFileMethod = null; - } - } - - // Get an input stream for a known file inside the expansion file ZIPs - InputStream fileStream; - try { - fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName); - } catch (Exception ex) { - ex.printStackTrace(); - fileStream = null; - } - - if (fileStream == null) { - throw new IOException(); - } - - return fileStream; - } - - // Messagebox - - /** Result of current messagebox. Also used for blocking the calling thread. */ - protected final int[] messageboxSelection = new int[1]; - - /** Id of current dialog. */ - protected int dialogs = 0; - - /** - * This method is called by SDL using JNI. - * Shows the messagebox from UI thread and block calling thread. - * buttonFlags, buttonIds and buttonTexts must have same length. - * @param buttonFlags array containing flags for every button. - * @param buttonIds array containing id for every button. - * @param buttonTexts array containing text for every button. - * @param colors null for default or array of length 5 containing colors. - * @return button id or -1. - */ - public int messageboxShowMessageBox( - final int flags, - final String title, - final String message, - final int[] buttonFlags, - final int[] buttonIds, - final String[] buttonTexts, - final int[] colors) { - - messageboxSelection[0] = -1; - - // sanity checks - - if ((buttonFlags.length != buttonIds.length) && (buttonIds.length != buttonTexts.length)) { - return -1; // implementation broken - } - - // collect arguments for Dialog - - final Bundle args = new Bundle(); - args.putInt("flags", flags); - args.putString("title", title); - args.putString("message", message); - args.putIntArray("buttonFlags", buttonFlags); - args.putIntArray("buttonIds", buttonIds); - args.putStringArray("buttonTexts", buttonTexts); - args.putIntArray("colors", colors); - - // trigger Dialog creation on UI thread - - runOnUiThread(new Runnable() { - @Override - public void run() { - showDialog(dialogs++, args); - } - }); - - // block the calling thread - - synchronized (messageboxSelection) { - try { - messageboxSelection.wait(); - } catch (InterruptedException ex) { - ex.printStackTrace(); - return -1; - } - } - - // return selected value - - return messageboxSelection[0]; - } - - @Override - protected Dialog onCreateDialog(int ignore, Bundle args) { - - // TODO set values from "flags" to messagebox dialog - - // get colors - - int[] colors = args.getIntArray("colors"); - int backgroundColor; - int textColor; - int buttonBorderColor; - int buttonBackgroundColor; - int buttonSelectedColor; - if (colors != null) { - int i = -1; - backgroundColor = colors[++i]; - textColor = colors[++i]; - buttonBorderColor = colors[++i]; - buttonBackgroundColor = colors[++i]; - buttonSelectedColor = colors[++i]; - } else { - backgroundColor = Color.TRANSPARENT; - textColor = Color.TRANSPARENT; - buttonBorderColor = Color.TRANSPARENT; - buttonBackgroundColor = Color.TRANSPARENT; - buttonSelectedColor = Color.TRANSPARENT; - } - - // create dialog with title and a listener to wake up calling thread - - final Dialog dialog = new Dialog(this); - dialog.setTitle(args.getString("title")); - dialog.setCancelable(false); - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface unused) { - synchronized (messageboxSelection) { - messageboxSelection.notify(); - } - } - }); - - // create text - - TextView message = new TextView(this); - message.setGravity(Gravity.CENTER); - message.setText(args.getString("message")); - if (textColor != Color.TRANSPARENT) { - message.setTextColor(textColor); - } - - // create buttons - - int[] buttonFlags = args.getIntArray("buttonFlags"); - int[] buttonIds = args.getIntArray("buttonIds"); - String[] buttonTexts = args.getStringArray("buttonTexts"); - - final SparseArray