From a9e88fefd1139600337ef2881f1be2866c3b0d89 Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Wed, 18 Mar 2015 08:43:57 +0000 Subject: [PATCH 1/5] enable ctypes wip, hopefully fixes for #301, #333, #319 --- distribute.sh | 1 - recipes/python/patches/disable-modules.patch | 2 +- recipes/python/recipe.sh | 11 +++++++++-- src/src/org/renpy/android/PythonService.java | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/distribute.sh b/distribute.sh index 1a79d14e30..adcda0a817 100755 --- a/distribute.sh +++ b/distribute.sh @@ -807,7 +807,6 @@ function run_distribute() { try find . | grep -E '*\.(py|pyc|so\.o|so\.a|so\.libs)$' | xargs rm # we are sure that all of theses will be never used on android (well...) - try rm -rf ctypes try rm -rf lib2to3 try rm -rf idlelib try rm -rf config/libpython*.a diff --git a/recipes/python/patches/disable-modules.patch b/recipes/python/patches/disable-modules.patch index fe96dcdcd8..3841488c40 100644 --- a/recipes/python/patches/disable-modules.patch +++ b/recipes/python/patches/disable-modules.patch @@ -5,7 +5,7 @@ # This global variable is used to hold the list of modules to be disabled. -disabled_module_list = [] -+disabled_module_list = ['spwd', '_ctypes','bz2','ossaudiodev','_curses','_curses_panel','readline','_locale','_bsddb','gdbm','dbm','nis','linuxaudiodev','crypt','_multiprocessing'] ++disabled_module_list = ['spwd','bz2','ossaudiodev','_curses','_curses_panel','readline','_locale','_bsddb','gdbm','dbm','nis','linuxaudiodev','crypt','_multiprocessing'] def add_dir_to_list(dirlist, dir): """Add the directory 'dir' to the list 'dirlist' (at the front) if diff --git a/recipes/python/recipe.sh b/recipes/python/recipe.sh index 4246bae97a..548c6a8e54 100644 --- a/recipes/python/recipe.sh +++ b/recipes/python/recipe.sh @@ -20,6 +20,7 @@ function prebuild_python() { fi try patch -p1 < $RECIPE_python/patches/Python-$VERSION_python-xcompile.patch + try patch -p1 < $RECIPE_python/patches/Python-$VERSION_python-ctypes-disable-wchar.patch try patch -p1 < $RECIPE_python/patches/disable-modules.patch try patch -p1 < $RECIPE_python/patches/fix-locale.patch try patch -p1 < $RECIPE_python/patches/fix-gethostbyaddr.patch @@ -92,8 +93,13 @@ function build_python() { export LDFLAGS="$LDFLAGS -L$SRC_PATH/obj/local/$ARCH/" fi - try ./configure --host=arm-eabi OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework - echo ./configure --host=arm-eabi OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework + # CFLAGS for python ctypes library + export CFLAGS="$CFLAGS -DNO_MALLINFO" + export BUILDARCH=x86_64-linux-gnu + export HOSTARCH=arm-eabi + + try ./configure --host=$HOSTARCH --build=$BUILDARCH OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework + echo ./configure --host=$HOSTARCH --build=$BUILDARCH OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework echo $MAKE HOSTPYTHON=$BUILD_python/hostpython HOSTPGEN=$BUILD_python/hostpgen CROSS_COMPILE_TARGET=yes INSTSONAME=libpython2.7.so cp HOSTPYTHON=$BUILD_python/hostpython python @@ -117,6 +123,7 @@ function build_python() { fi try cp $BUILD_hostpython/hostpython $HOSTPYTHON try cp libpython2.7.so $LIBS_PATH/ + try cp -a build/lib.linux-x86_64-2.7/_ctypes*.so $LIBS_PATH # reduce python rm -rf "$BUILD_PATH/python-install/lib/python2.7/test" diff --git a/src/src/org/renpy/android/PythonService.java b/src/src/org/renpy/android/PythonService.java index 321ee6094d..7189ecbd29 100644 --- a/src/src/org/renpy/android/PythonService.java +++ b/src/src/org/renpy/android/PythonService.java @@ -85,9 +85,11 @@ public void run(){ System.loadLibrary("python2.7"); System.loadLibrary("application"); System.loadLibrary("sdl_main"); + System.loadLibrary("ctypes"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); try { System.loadLibrary("sqlite3"); From e8c0a4e1bdc29f86da131768d22bd8cdd73a68d3 Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Wed, 18 Mar 2015 08:43:57 +0000 Subject: [PATCH 2/5] enable ctypes wip, hopefully fixes for #301, #333, #319 --- distribute.sh | 1 - .../Python-2.7.2-ctypes-disable-wchar.patch | 63 +++++++++++++++++++ recipes/python/patches/disable-modules.patch | 2 +- recipes/python/recipe.sh | 11 +++- src/src/org/renpy/android/PythonService.java | 2 + 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch diff --git a/distribute.sh b/distribute.sh index 1a79d14e30..adcda0a817 100755 --- a/distribute.sh +++ b/distribute.sh @@ -807,7 +807,6 @@ function run_distribute() { try find . | grep -E '*\.(py|pyc|so\.o|so\.a|so\.libs)$' | xargs rm # we are sure that all of theses will be never used on android (well...) - try rm -rf ctypes try rm -rf lib2to3 try rm -rf idlelib try rm -rf config/libpython*.a diff --git a/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch b/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch new file mode 100644 index 0000000000..07244877eb --- /dev/null +++ b/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch @@ -0,0 +1,63 @@ +diff -uNr Python-2.7.2.orig/Lib/ctypes/__init__.py Python-2.7.2/Lib/ctypes/__init__.py +--- Python-2.7.2.orig/Lib/ctypes/__init__.py 2011-06-11 17:46:24.000000000 +0200 ++++ Python-2.7.2/Lib/ctypes/__init__.py 2012-08-30 13:40:38.837698797 +0200 +@@ -272,31 +272,34 @@ + else: + set_conversion_mode("ascii", "strict") + +- class c_wchar_p(_SimpleCData): +- _type_ = "Z" +- +- class c_wchar(_SimpleCData): +- _type_ = "u" +- +- POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param +- +- def create_unicode_buffer(init, size=None): +- """create_unicode_buffer(aString) -> character array +- create_unicode_buffer(anInteger) -> character array +- create_unicode_buffer(aString, anInteger) -> character array +- """ +- if isinstance(init, (str, unicode)): +- if size is None: +- size = len(init)+1 +- buftype = c_wchar * size +- buf = buftype() +- buf.value = init +- return buf +- elif isinstance(init, (int, long)): +- buftype = c_wchar * init +- buf = buftype() +- return buf +- raise TypeError(init) ++# The wchar stuff causes a crash on Android (the bionic C library doesn't ++# implement wchar_t anyway) ++# ++# class c_wchar_p(_SimpleCData): ++# _type_ = "Z" ++# ++# class c_wchar(_SimpleCData): ++# _type_ = "u" ++# ++# POINTER(c_wchar).from_param = c_wchar_p.from_param #_SimpleCData.c_wchar_p_from_param ++# ++# def create_unicode_buffer(init, size=None): ++# """create_unicode_buffer(aString) -> character array ++# create_unicode_buffer(anInteger) -> character array ++# create_unicode_buffer(aString, anInteger) -> character array ++# """ ++# if isinstance(init, (str, unicode)): ++# if size is None: ++# size = len(init)+1 ++# buftype = c_wchar * size ++# buf = buftype() ++# buf.value = init ++# return buf ++# elif isinstance(init, (int, long)): ++# buftype = c_wchar * init ++# buf = buftype() ++# return buf ++# raise TypeError(init) + + POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param + diff --git a/recipes/python/patches/disable-modules.patch b/recipes/python/patches/disable-modules.patch index fe96dcdcd8..3841488c40 100644 --- a/recipes/python/patches/disable-modules.patch +++ b/recipes/python/patches/disable-modules.patch @@ -5,7 +5,7 @@ # This global variable is used to hold the list of modules to be disabled. -disabled_module_list = [] -+disabled_module_list = ['spwd', '_ctypes','bz2','ossaudiodev','_curses','_curses_panel','readline','_locale','_bsddb','gdbm','dbm','nis','linuxaudiodev','crypt','_multiprocessing'] ++disabled_module_list = ['spwd','bz2','ossaudiodev','_curses','_curses_panel','readline','_locale','_bsddb','gdbm','dbm','nis','linuxaudiodev','crypt','_multiprocessing'] def add_dir_to_list(dirlist, dir): """Add the directory 'dir' to the list 'dirlist' (at the front) if diff --git a/recipes/python/recipe.sh b/recipes/python/recipe.sh index 4246bae97a..548c6a8e54 100644 --- a/recipes/python/recipe.sh +++ b/recipes/python/recipe.sh @@ -20,6 +20,7 @@ function prebuild_python() { fi try patch -p1 < $RECIPE_python/patches/Python-$VERSION_python-xcompile.patch + try patch -p1 < $RECIPE_python/patches/Python-$VERSION_python-ctypes-disable-wchar.patch try patch -p1 < $RECIPE_python/patches/disable-modules.patch try patch -p1 < $RECIPE_python/patches/fix-locale.patch try patch -p1 < $RECIPE_python/patches/fix-gethostbyaddr.patch @@ -92,8 +93,13 @@ function build_python() { export LDFLAGS="$LDFLAGS -L$SRC_PATH/obj/local/$ARCH/" fi - try ./configure --host=arm-eabi OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework - echo ./configure --host=arm-eabi OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework + # CFLAGS for python ctypes library + export CFLAGS="$CFLAGS -DNO_MALLINFO" + export BUILDARCH=x86_64-linux-gnu + export HOSTARCH=arm-eabi + + try ./configure --host=$HOSTARCH --build=$BUILDARCH OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework + echo ./configure --host=$HOSTARCH --build=$BUILDARCH OPT=$OFLAG --prefix="$BUILD_PATH/python-install" --enable-shared --disable-toolbox-glue --disable-framework echo $MAKE HOSTPYTHON=$BUILD_python/hostpython HOSTPGEN=$BUILD_python/hostpgen CROSS_COMPILE_TARGET=yes INSTSONAME=libpython2.7.so cp HOSTPYTHON=$BUILD_python/hostpython python @@ -117,6 +123,7 @@ function build_python() { fi try cp $BUILD_hostpython/hostpython $HOSTPYTHON try cp libpython2.7.so $LIBS_PATH/ + try cp -a build/lib.linux-x86_64-2.7/_ctypes*.so $LIBS_PATH # reduce python rm -rf "$BUILD_PATH/python-install/lib/python2.7/test" diff --git a/src/src/org/renpy/android/PythonService.java b/src/src/org/renpy/android/PythonService.java index 321ee6094d..7189ecbd29 100644 --- a/src/src/org/renpy/android/PythonService.java +++ b/src/src/org/renpy/android/PythonService.java @@ -85,9 +85,11 @@ public void run(){ System.loadLibrary("python2.7"); System.loadLibrary("application"); System.loadLibrary("sdl_main"); + System.loadLibrary("ctypes"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); try { System.loadLibrary("sqlite3"); From f0c74992009e7250a561a6bddd2d1df3b804d8d8 Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Thu, 19 Mar 2015 13:58:25 +0000 Subject: [PATCH 3/5] adjusted the patch file to try a new build --- .../Python-2.7.2-ctypes-disable-wchar.patch | 59 ++++++++++++++++++- .../python/patches/ctypes-find-library.patch | 21 +++++++ recipes/python/recipe.sh | 3 +- 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 recipes/python/patches/ctypes-find-library.patch diff --git a/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch b/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch index 07244877eb..19d8915eaa 100644 --- a/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch +++ b/recipes/python/patches/Python-2.7.2-ctypes-disable-wchar.patch @@ -1,6 +1,6 @@ -diff -uNr Python-2.7.2.orig/Lib/ctypes/__init__.py Python-2.7.2/Lib/ctypes/__init__.py ---- Python-2.7.2.orig/Lib/ctypes/__init__.py 2011-06-11 17:46:24.000000000 +0200 -+++ Python-2.7.2/Lib/ctypes/__init__.py 2012-08-30 13:40:38.837698797 +0200 +diff -ur '--exclude=*~' Python-2.7.2.orig/Lib/ctypes/__init__.py Python-2.7.2/Lib/ctypes/__init__.py +--- Python-2.7.2.orig/Lib/ctypes/__init__.py 2011-06-11 16:46:24.000000000 +0100 ++++ Python-2.7.2/Lib/ctypes/__init__.py 2015-03-19 12:32:45.747723687 +0000 @@ -272,31 +272,34 @@ else: set_conversion_mode("ascii", "strict") @@ -61,3 +61,56 @@ diff -uNr Python-2.7.2.orig/Lib/ctypes/__init__.py Python-2.7.2/Lib/ctypes/__ini POINTER(c_char).from_param = c_char_p.from_param #_SimpleCData.c_char_p_from_param +diff -ur '--exclude=*~' Python-2.7.2.orig/Modules/_ctypes/callproc.c Python-2.7.2/Modules/_ctypes/callproc.c +--- Python-2.7.2.orig/Modules/_ctypes/callproc.c 2015-03-19 11:56:40.668159317 +0000 ++++ Python-2.7.2/Modules/_ctypes/callproc.c 2015-03-19 11:45:45.898288000 +0000 +@@ -1423,7 +1423,7 @@ + mode |= RTLD_NOW; + handle = ctypes_dlopen(name, mode); + if (!handle) { +- char *errmsg = ctypes_dlerror(); ++ const char *errmsg = ctypes_dlerror(); + if (!errmsg) + errmsg = "dlopen() error"; + PyErr_SetString(PyExc_OSError, +diff -ur '--exclude=*~' Python-2.7.2.orig/Modules/_ctypes/libffi/src/dlmalloc.c Python-2.7.2/Modules/_ctypes/libffi/src/dlmalloc.c +--- Python-2.7.2.orig/Modules/_ctypes/libffi/src/dlmalloc.c 2015-03-19 13:26:58.928438829 +0000 ++++ Python-2.7.2/Modules/_ctypes/libffi/src/dlmalloc.c 2015-03-19 15:32:19.042396376 +0000 +@@ -614,18 +614,6 @@ + #include "/usr/include/malloc.h" + #else /* HAVE_USR_INCLUDE_MALLOC_H */ + +-struct mallinfo { +- MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ +- MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ +- MALLINFO_FIELD_TYPE smblks; /* always 0 */ +- MALLINFO_FIELD_TYPE hblks; /* always 0 */ +- MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ +- MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ +- MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ +- MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ +- MALLINFO_FIELD_TYPE fordblks; /* total free space */ +- MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +-}; + + #endif /* HAVE_USR_INCLUDE_MALLOC_H */ + #endif /* NO_MALLINFO */ +@@ -966,7 +954,7 @@ + p = malloc(n); + assert(malloc_usable_size(p) >= 256); + */ +-size_t dlmalloc_usable_size(void*); ++size_t dlmalloc_usable_size(const void*); + + /* + malloc_stats(); +@@ -4384,7 +4372,7 @@ + internal_malloc_stats(gm); + } + +-size_t dlmalloc_usable_size(void* mem) { ++size_t dlmalloc_usable_size(const void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (cinuse(p)) + diff --git a/recipes/python/patches/ctypes-find-library.patch b/recipes/python/patches/ctypes-find-library.patch new file mode 100644 index 0000000000..2f3c6fb2cd --- /dev/null +++ b/recipes/python/patches/ctypes-find-library.patch @@ -0,0 +1,21 @@ +--- Python-2.7.2.orig/Lib/ctypes/util.py 2011-06-11 16:46:24.000000000 +0100 ++++ Python-2.7.2/Lib/ctypes/util.py 2015-03-26 13:45:33.322172603 +0000 +@@ -83,7 +83,17 @@ + except ValueError: + continue + return None +- ++elif os.name == "posix" and sys.platform == "linux3": ++ def find_library(name): ++ """ hack to find librarys for kivy and android ++ split the path and get the first parts which will give us ++ the app path something like /data/data/org.app.foo/""" ++ app_root = os.path.abspath('./').split(os.path.sep)[0:4] ++ lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib' ++ for filename in os.listdir(lib_search): ++ if filename.endswith('.so') and name in filename: ++ return lib_search + os.path.sep + filename ++ return None + elif os.name == "posix": + # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump + import re, tempfile, errno diff --git a/recipes/python/recipe.sh b/recipes/python/recipe.sh index 548c6a8e54..27200ffef9 100644 --- a/recipes/python/recipe.sh +++ b/recipes/python/recipe.sh @@ -32,6 +32,7 @@ function prebuild_python() { try patch -p1 < $RECIPE_python/patches/fix-remove-corefoundation.patch try patch -p1 < $RECIPE_python/patches/fix-dynamic-lookup.patch try patch -p1 < $RECIPE_python/patches/fix-dlfcn.patch + try patch -p1 < $RECIPE_python/patches/ctypes-find-library.patch system=$(uname -s) if [ "X$system" == "XDarwin" ]; then @@ -94,7 +95,7 @@ function build_python() { fi # CFLAGS for python ctypes library - export CFLAGS="$CFLAGS -DNO_MALLINFO" + #export CFLAGS="$CFLAGS -DNO_MALLINFO" export BUILDARCH=x86_64-linux-gnu export HOSTARCH=arm-eabi From 6241ac1fe5578c7356c3c6bf650b301a1806b726 Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Sun, 10 May 2015 11:50:20 +0100 Subject: [PATCH 4/5] update ctypes patch, it now does no checking for system type and just assumes android and runs our custom library lookup function --- .../python/patches/ctypes-find-library.patch | 270 ++++++++++++++++-- 1 file changed, 250 insertions(+), 20 deletions(-) diff --git a/recipes/python/patches/ctypes-find-library.patch b/recipes/python/patches/ctypes-find-library.patch index 2f3c6fb2cd..cf2117d5cb 100644 --- a/recipes/python/patches/ctypes-find-library.patch +++ b/recipes/python/patches/ctypes-find-library.patch @@ -1,21 +1,251 @@ +diff -ur Python-2.7.2.orig/Lib/ctypes/util.py Python-2.7.2/Lib/ctypes/util.py --- Python-2.7.2.orig/Lib/ctypes/util.py 2011-06-11 16:46:24.000000000 +0100 -+++ Python-2.7.2/Lib/ctypes/util.py 2015-03-26 13:45:33.322172603 +0000 -@@ -83,7 +83,17 @@ - except ValueError: - continue - return None -- -+elif os.name == "posix" and sys.platform == "linux3": -+ def find_library(name): -+ """ hack to find librarys for kivy and android -+ split the path and get the first parts which will give us -+ the app path something like /data/data/org.app.foo/""" -+ app_root = os.path.abspath('./').split(os.path.sep)[0:4] -+ lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib' -+ for filename in os.listdir(lib_search): -+ if filename.endswith('.so') and name in filename: -+ return lib_search + os.path.sep + filename -+ return None - elif os.name == "posix": - # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump - import re, tempfile, errno ++++ Python-2.7.2/Lib/ctypes/util.py 2015-05-10 10:37:49.258720992 +0100 +@@ -3,237 +3,16 @@ + ###################################################################### + import sys, os + +-# find_library(name) returns the pathname of a library, or None. +-if os.name == "nt": +- +- def _get_build_version(): +- """Return the version of MSVC that was used to build Python. +- +- For Python 2.3 and up, the version number is included in +- sys.version. For earlier versions, assume the compiler is MSVC 6. +- """ +- # This function was copied from Lib/distutils/msvccompiler.py +- prefix = "MSC v." +- i = sys.version.find(prefix) +- if i == -1: +- return 6 +- i = i + len(prefix) +- s, rest = sys.version[i:].split(" ", 1) +- majorVersion = int(s[:-2]) - 6 +- minorVersion = int(s[2:3]) / 10.0 +- # I don't think paths are affected by minor version in version 6 +- if majorVersion == 6: +- minorVersion = 0 +- if majorVersion >= 6: +- return majorVersion + minorVersion +- # else we don't know what version of the compiler this is +- return None +- +- def find_msvcrt(): +- """Return the name of the VC runtime dll""" +- version = _get_build_version() +- if version is None: +- # better be safe than sorry +- return None +- if version <= 6: +- clibname = 'msvcrt' +- else: +- clibname = 'msvcr%d' % (version * 10) +- +- # If python was built with in debug mode +- import imp +- if imp.get_suffixes()[0][0] == '_d.pyd': +- clibname += 'd' +- return clibname+'.dll' +- +- def find_library(name): +- if name in ('c', 'm'): +- return find_msvcrt() +- # See MSDN for the REAL search order. +- for directory in os.environ['PATH'].split(os.pathsep): +- fname = os.path.join(directory, name) +- if os.path.isfile(fname): +- return fname +- if fname.lower().endswith(".dll"): +- continue +- fname = fname + ".dll" +- if os.path.isfile(fname): +- return fname +- return None +- +-if os.name == "ce": +- # search path according to MSDN: +- # - absolute path specified by filename +- # - The .exe launch directory +- # - the Windows directory +- # - ROM dll files (where are they?) +- # - OEM specified search path: HKLM\Loader\SystemPath +- def find_library(name): +- return name +- +-if os.name == "posix" and sys.platform == "darwin": +- from ctypes.macholib.dyld import dyld_find as _dyld_find +- def find_library(name): +- possible = ['lib%s.dylib' % name, +- '%s.dylib' % name, +- '%s.framework/%s' % (name, name)] +- for name in possible: +- try: +- return _dyld_find(name) +- except ValueError: +- continue +- return None +- +-elif os.name == "posix": +- # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump +- import re, tempfile, errno +- +- def _findLib_gcc(name): +- expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) +- fdout, ccout = tempfile.mkstemp() +- os.close(fdout) +- cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \ +- '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name +- try: +- f = os.popen(cmd) +- try: +- trace = f.read() +- finally: +- rv = f.close() +- finally: +- try: +- os.unlink(ccout) +- except OSError, e: +- if e.errno != errno.ENOENT: +- raise +- if rv == 10: +- raise OSError, 'gcc or cc command not found' +- res = re.search(expr, trace) +- if not res: +- return None +- return res.group(0) +- +- +- if sys.platform == "sunos5": +- # use /usr/ccs/bin/dump on solaris +- def _get_soname(f): +- if not f: +- return None +- cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f +- f = os.popen(cmd) +- try: +- data = f.read() +- finally: +- f.close() +- res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data) +- if not res: +- return None +- return res.group(1) +- else: +- def _get_soname(f): +- # assuming GNU binutils / ELF +- if not f: +- return None +- cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ +- "objdump -p -j .dynamic 2>/dev/null " + f +- f = os.popen(cmd) +- dump = f.read() +- rv = f.close() +- if rv == 10: +- raise OSError, 'objdump command not found' +- f = os.popen(cmd) +- try: +- data = f.read() +- finally: +- f.close() +- res = re.search(r'\sSONAME\s+([^\s]+)', data) +- if not res: +- return None +- return res.group(1) +- +- if (sys.platform.startswith("freebsd") +- or sys.platform.startswith("openbsd") +- or sys.platform.startswith("dragonfly")): +- +- def _num_version(libname): +- # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] +- parts = libname.split(".") +- nums = [] +- try: +- while parts: +- nums.insert(0, int(parts.pop())) +- except ValueError: +- pass +- return nums or [ sys.maxint ] +- +- def find_library(name): +- ename = re.escape(name) +- expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) +- f = os.popen('/sbin/ldconfig -r 2>/dev/null') +- try: +- data = f.read() +- finally: +- f.close() +- res = re.findall(expr, data) +- if not res: +- return _get_soname(_findLib_gcc(name)) +- res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) +- return res[-1] +- +- else: +- +- def _findLib_ldconfig(name): +- # XXX assuming GLIBC's ldconfig (with option -p) +- expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) +- f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') +- try: +- data = f.read() +- finally: +- f.close() +- res = re.search(expr, data) +- if not res: +- # Hm, this works only for libs needed by the python executable. +- cmd = 'ldd %s 2>/dev/null' % sys.executable +- f = os.popen(cmd) +- try: +- data = f.read() +- finally: +- f.close() +- res = re.search(expr, data) +- if not res: +- return None +- return res.group(0) +- +- def _findSoname_ldconfig(name): +- import struct +- if struct.calcsize('l') == 4: +- machine = os.uname()[4] + '-32' +- else: +- machine = os.uname()[4] + '-64' +- mach_map = { +- 'x86_64-64': 'libc6,x86-64', +- 'ppc64-64': 'libc6,64bit', +- 'sparc64-64': 'libc6,64bit', +- 's390x-64': 'libc6,64bit', +- 'ia64-64': 'libc6,IA-64', +- } +- abi_type = mach_map.get(machine, 'libc6') +- +- # XXX assuming GLIBC's ldconfig (with option -p) +- expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ +- % (abi_type, re.escape(name)) +- f = os.popen('/sbin/ldconfig -p 2>/dev/null') +- try: +- data = f.read() +- finally: +- f.close() +- res = re.search(expr, data) +- if not res: +- return None +- return res.group(1) +- +- def find_library(name): +- return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) ++def find_library(name): ++ """ hack to find librarys for kivy and android ++ split the path and get the first parts which will give us ++ the app path something like /data/data/org.app.foo/""" ++ app_root = os.path.abspath('./').split(os.path.sep)[0:4] ++ lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib' ++ for filename in os.listdir(lib_search): ++ if filename.endswith('.so') and name in filename: ++ return lib_search + os.path.sep + filename ++ return None + + ################################################################ + # test code From 6c352dd351c46cc098d2db2aa5420cc7fd06b7ff Mon Sep 17 00:00:00 2001 From: Oliver Marks Date: Sun, 10 May 2015 15:54:01 +0100 Subject: [PATCH 5/5] PR snagging --- .../python/patches/ctypes-find-library.patch | 271 ++---------------- recipes/python/recipe.sh | 4 +- src/src/org/renpy/android/PythonService.java | 9 +- 3 files changed, 33 insertions(+), 251 deletions(-) diff --git a/recipes/python/patches/ctypes-find-library.patch b/recipes/python/patches/ctypes-find-library.patch index cf2117d5cb..68fa93f526 100644 --- a/recipes/python/patches/ctypes-find-library.patch +++ b/recipes/python/patches/ctypes-find-library.patch @@ -1,251 +1,28 @@ diff -ur Python-2.7.2.orig/Lib/ctypes/util.py Python-2.7.2/Lib/ctypes/util.py --- Python-2.7.2.orig/Lib/ctypes/util.py 2011-06-11 16:46:24.000000000 +0100 -+++ Python-2.7.2/Lib/ctypes/util.py 2015-05-10 10:37:49.258720992 +0100 -@@ -3,237 +3,16 @@ - ###################################################################### - import sys, os ++++ Python-2.7.2/Lib/ctypes/util.py 2015-05-10 15:50:18.906203529 +0100 +@@ -71,7 +71,21 @@ + def find_library(name): + return name --# find_library(name) returns the pathname of a library, or None. --if os.name == "nt": -- -- def _get_build_version(): -- """Return the version of MSVC that was used to build Python. -- -- For Python 2.3 and up, the version number is included in -- sys.version. For earlier versions, assume the compiler is MSVC 6. -- """ -- # This function was copied from Lib/distutils/msvccompiler.py -- prefix = "MSC v." -- i = sys.version.find(prefix) -- if i == -1: -- return 6 -- i = i + len(prefix) -- s, rest = sys.version[i:].split(" ", 1) -- majorVersion = int(s[:-2]) - 6 -- minorVersion = int(s[2:3]) / 10.0 -- # I don't think paths are affected by minor version in version 6 -- if majorVersion == 6: -- minorVersion = 0 -- if majorVersion >= 6: -- return majorVersion + minorVersion -- # else we don't know what version of the compiler this is -- return None -- -- def find_msvcrt(): -- """Return the name of the VC runtime dll""" -- version = _get_build_version() -- if version is None: -- # better be safe than sorry -- return None -- if version <= 6: -- clibname = 'msvcrt' -- else: -- clibname = 'msvcr%d' % (version * 10) -- -- # If python was built with in debug mode -- import imp -- if imp.get_suffixes()[0][0] == '_d.pyd': -- clibname += 'd' -- return clibname+'.dll' -- -- def find_library(name): -- if name in ('c', 'm'): -- return find_msvcrt() -- # See MSDN for the REAL search order. -- for directory in os.environ['PATH'].split(os.pathsep): -- fname = os.path.join(directory, name) -- if os.path.isfile(fname): -- return fname -- if fname.lower().endswith(".dll"): -- continue -- fname = fname + ".dll" -- if os.path.isfile(fname): -- return fname -- return None -- --if os.name == "ce": -- # search path according to MSDN: -- # - absolute path specified by filename -- # - The .exe launch directory -- # - the Windows directory -- # - ROM dll files (where are they?) -- # - OEM specified search path: HKLM\Loader\SystemPath -- def find_library(name): -- return name -- -if os.name == "posix" and sys.platform == "darwin": -- from ctypes.macholib.dyld import dyld_find as _dyld_find -- def find_library(name): -- possible = ['lib%s.dylib' % name, -- '%s.dylib' % name, -- '%s.framework/%s' % (name, name)] -- for name in possible: -- try: -- return _dyld_find(name) -- except ValueError: -- continue -- return None -- --elif os.name == "posix": -- # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump -- import re, tempfile, errno -- -- def _findLib_gcc(name): -- expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) -- fdout, ccout = tempfile.mkstemp() -- os.close(fdout) -- cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \ -- '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name -- try: -- f = os.popen(cmd) -- try: -- trace = f.read() -- finally: -- rv = f.close() -- finally: -- try: -- os.unlink(ccout) -- except OSError, e: -- if e.errno != errno.ENOENT: -- raise -- if rv == 10: -- raise OSError, 'gcc or cc command not found' -- res = re.search(expr, trace) -- if not res: -- return None -- return res.group(0) -- -- -- if sys.platform == "sunos5": -- # use /usr/ccs/bin/dump on solaris -- def _get_soname(f): -- if not f: -- return None -- cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f -- f = os.popen(cmd) -- try: -- data = f.read() -- finally: -- f.close() -- res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data) -- if not res: -- return None -- return res.group(1) -- else: -- def _get_soname(f): -- # assuming GNU binutils / ELF -- if not f: -- return None -- cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ -- "objdump -p -j .dynamic 2>/dev/null " + f -- f = os.popen(cmd) -- dump = f.read() -- rv = f.close() -- if rv == 10: -- raise OSError, 'objdump command not found' -- f = os.popen(cmd) -- try: -- data = f.read() -- finally: -- f.close() -- res = re.search(r'\sSONAME\s+([^\s]+)', data) -- if not res: -- return None -- return res.group(1) -- -- if (sys.platform.startswith("freebsd") -- or sys.platform.startswith("openbsd") -- or sys.platform.startswith("dragonfly")): -- -- def _num_version(libname): -- # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] -- parts = libname.split(".") -- nums = [] -- try: -- while parts: -- nums.insert(0, int(parts.pop())) -- except ValueError: -- pass -- return nums or [ sys.maxint ] -- -- def find_library(name): -- ename = re.escape(name) -- expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) -- f = os.popen('/sbin/ldconfig -r 2>/dev/null') -- try: -- data = f.read() -- finally: -- f.close() -- res = re.findall(expr, data) -- if not res: -- return _get_soname(_findLib_gcc(name)) -- res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) -- return res[-1] -- -- else: -- -- def _findLib_ldconfig(name): -- # XXX assuming GLIBC's ldconfig (with option -p) -- expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) -- f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null') -- try: -- data = f.read() -- finally: -- f.close() -- res = re.search(expr, data) -- if not res: -- # Hm, this works only for libs needed by the python executable. -- cmd = 'ldd %s 2>/dev/null' % sys.executable -- f = os.popen(cmd) -- try: -- data = f.read() -- finally: -- f.close() -- res = re.search(expr, data) -- if not res: -- return None -- return res.group(0) -- -- def _findSoname_ldconfig(name): -- import struct -- if struct.calcsize('l') == 4: -- machine = os.uname()[4] + '-32' -- else: -- machine = os.uname()[4] + '-64' -- mach_map = { -- 'x86_64-64': 'libc6,x86-64', -- 'ppc64-64': 'libc6,64bit', -- 'sparc64-64': 'libc6,64bit', -- 's390x-64': 'libc6,64bit', -- 'ia64-64': 'libc6,IA-64', -- } -- abi_type = mach_map.get(machine, 'libc6') -- -- # XXX assuming GLIBC's ldconfig (with option -p) -- expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \ -- % (abi_type, re.escape(name)) -- f = os.popen('/sbin/ldconfig -p 2>/dev/null') -- try: -- data = f.read() -- finally: -- f.close() -- res = re.search(expr, data) -- if not res: -- return None -- return res.group(1) -- -- def find_library(name): -- return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) -+def find_library(name): -+ """ hack to find librarys for kivy and android -+ split the path and get the first parts which will give us -+ the app path something like /data/data/org.app.foo/""" -+ app_root = os.path.abspath('./').split(os.path.sep)[0:4] -+ lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib' -+ for filename in os.listdir(lib_search): -+ if filename.endswith('.so') and name in filename: -+ return lib_search + os.path.sep + filename -+ return None - - ################################################################ - # test code ++# this test is for android specifically shoudl match here and ignore any ++# of the other platform tests below ++if os.name == "posix": ++ def find_library(name): ++ """ hack to find librarys for kivy and android ++ split the path and get the first parts which will give us ++ the app path something like /data/data/org.app.foo/""" ++ app_root = os.path.abspath('./').split(os.path.sep)[0:4] ++ lib_search = os.path.sep.join(app_root) + os.path.sep + 'lib' ++ for filename in os.listdir(lib_search): ++ if filename.endswith('.so') and name in filename: ++ return lib_search + os.path.sep + filename ++ return None ++ ++elif os.name == "posix" and sys.platform == "darwin": + from ctypes.macholib.dyld import dyld_find as _dyld_find + def find_library(name): + possible = ['lib%s.dylib' % name, +Only in Python-2.7.2/Lib/ctypes: util.py.save +Only in Python-2.7.2/Lib/ctypes: util.py.save.1 diff --git a/recipes/python/recipe.sh b/recipes/python/recipe.sh index 27200ffef9..69e1b6c26a 100644 --- a/recipes/python/recipe.sh +++ b/recipes/python/recipe.sh @@ -32,7 +32,7 @@ function prebuild_python() { try patch -p1 < $RECIPE_python/patches/fix-remove-corefoundation.patch try patch -p1 < $RECIPE_python/patches/fix-dynamic-lookup.patch try patch -p1 < $RECIPE_python/patches/fix-dlfcn.patch - try patch -p1 < $RECIPE_python/patches/ctypes-find-library.patch + try patch -p1 < $RECIPE_python/patches/ctypes-find-library.patch system=$(uname -s) if [ "X$system" == "XDarwin" ]; then @@ -106,7 +106,7 @@ function build_python() { # FIXME, the first time, we got a error at: # python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h - # /home/tito/code/python-for-android/build/python/Python-2.7.2/python: 1: Syntax error: word unexpected (expecting ")") + # /home/tito/code/python-for-android/build/python/Python-2.7.2/python: 1: Syntax error: word unexpected (expecting ")") # because at this time, python is arm, not x86. even that, why /usr/include/netinet/in.h is used ? # check if we can avoid this part. diff --git a/src/src/org/renpy/android/PythonService.java b/src/src/org/renpy/android/PythonService.java index 7189ecbd29..2128f9bb34 100644 --- a/src/src/org/renpy/android/PythonService.java +++ b/src/src/org/renpy/android/PythonService.java @@ -85,11 +85,16 @@ public void run(){ System.loadLibrary("python2.7"); System.loadLibrary("application"); System.loadLibrary("sdl_main"); - System.loadLibrary("ctypes"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_io.so"); System.load(getFilesDir() + "/lib/python2.7/lib-dynload/unicodedata.so"); - System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); + + try { + System.loadLibrary("ctypes"); + System.load(getFilesDir() + "/lib/python2.7/lib-dynload/_ctypes.so"); + } catch(UnsatisfiedLinkError e) { + } try { System.loadLibrary("sqlite3");