first pass with a brand new tool. starting to write the hostpython recipe

This commit is contained in:
Mathieu Virbel 2015-02-01 18:35:28 +01:00
parent 55345e1cae
commit 577dea036e
17 changed files with 850 additions and 0 deletions

0
recipes/__init__.py Normal file
View file

BIN
recipes/__init__.pyc Normal file

Binary file not shown.

7
recipes/audiostream.py Normal file
View file

@ -0,0 +1,7 @@
from toolchain import Recipe
class AudiostreamRecipe(Recipe):
version = "master"
url = "https://github.com/kivy/audiostream/archive/{version}.zip"
recipe = AudiostreamRecipe()

View file

@ -0,0 +1,52 @@
posix posixmodule.c # posix (UNIX) system calls
errno errnomodule.c # posix (UNIX) errno values
pwd pwdmodule.c # this is needed to find out the user's home dir
# if $HOME is not set
_sre _sre.c # Fredrik Lundh's new regular expressions
_codecs _codecsmodule.c # access to the builtin codecs and codec registry
zipimport zipimport.c
_symtable symtablemodule.c
array arraymodule.c # array objects
cmath cmathmodule.c # -lm # complex math library functions
math mathmodule.c # -lm # math library functions, e.g. sin()
_struct _struct.c # binary structure packing/unpacking
time timemodule.c # -lm # time operations and variables
operator operator.c # operator.add() and similar goodies
_weakref _weakref.c # basic weak reference support
_random _randommodule.c # Random number generator
_collections _collectionsmodule.c # Container types
itertools itertoolsmodule.c # Functions creating iterators for efficient looping
strop stropmodule.c # String manipulations
_functools _functoolsmodule.c # Tools for working with functions and callable objects
_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator
datetime datetimemodule.c # date/time type
_bisect _bisectmodule.c # Bisection algorithms
fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
select selectmodule.c # select(2); not on ancient System V
_socket socketmodule.c
_md5 md5module.c md5.c
_sha shamodule.c
_sha256 sha256module.c
_sha512 sha512module.c
binascii binascii.c
parser parsermodule.c
cStringIO cStringIO.c
cPickle cPickle.c
zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
xxsubtype xxsubtype.c
unicodedata unicodedata.c # static Unicode character database
# Theses modules are used by Kivy inside other module
# json in Settings, _io by zipfile...
_json _json.c
_io _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c
_heapq _heapqmodule.c
# Special inclusion for sqlite3
_sqlite3 -DSQLITE_OMIT_LOAD_EXTENSION _sqlite/cache.c _sqlite/microprotocols.c _sqlite/row.c _sqlite/connection.c _sqlite/module.c _sqlite/statement.c _sqlite/cursor.c _sqlite/prepare_protocol.c _sqlite/util.c
# Include expat
pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI
# Future (used by numpy)
future_builtins future_builtins.c

View file

@ -0,0 +1,2 @@
# Ctypes
_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c -I$(srcdir)/../../build/include/ffi

View file

@ -0,0 +1,40 @@
from toolchain import Recipe, shprint
from os.path import join
import sh
class HostpythonRecipe(Recipe):
version = "2.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
def prebuild_arch(self, arch):
# common to all archs
if not self.has_marker("patched"):
self.apply_patch("ssize-t-max.patch")
self.apply_patch("dynload.patch")
self.apply_patch("static-_sqlite3.patch")
self.copy_file("ModulesSetup", "Modules/Setup.local")
self.copy_file("_scproxy.py", "Lib/_scproxy.py")
#self.copy_file("Setup.dist", "Modules/Setup.dist")
self.set_marker("patched")
super(HostpythonRecipe, self).prebuild_arch(arch)
def build_i386(self):
sdk_path = sh.xcrun(
"--sdk", "macosx",
"--show-sdk-path").splitlines()[0]
build_env = self.ctx.env.copy()
build_env["CC"] = "clang -Qunused-arguments -fcolor-diagnostics"
build_env["LDFLAGS"] = "-lsqlite3"
build_env["CFLAGS"] = "--sysroot={}".format(sdk_path)
build_env["PWD"] = self.build_dir
configure = sh.Command(join(self.build_dir, "configure"))
print "-->"
shprint(configure, _env=build_env)
sh.make("-C", self.build_dir, "-j4", "python.exe", "Parser/pgen")
print "<--"
recipe = HostpythonRecipe()

Binary file not shown.

View file

@ -0,0 +1,10 @@
'''
Stub functions for _scproxy on iOS
No proxy is supported yet.
'''
def _get_proxy_settings():
return {'exclude_simple': 1}
def _get_proxies():
return {}

View file

@ -0,0 +1,34 @@
--- Python2.7-old/Modules/_ctypes/cfield.c 2010-05-09 16:46:46.000000000 +0200
+++ Python2.7-new/Modules/_ctypes/cfield.c 2013-08-27 00:21:15.000000000 +0200
@@ -1747,24 +1747,6 @@
} ffi_type;
*/
-/* align and size are bogus for void, but they must not be zero */
-ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
-
-ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
-ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
-
-ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
-ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
-
-ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
-ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
-
-ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
-ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
-
-ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
-ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
-
#ifdef ffi_type_longdouble
#undef ffi_type_longdouble
#endif
@@ -1772,6 +1754,4 @@
ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
FFI_TYPE_LONGDOUBLE };
-ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
-
/*---------------- EOF ----------------*/

View file

@ -0,0 +1,24 @@
--- Python-2.7.1/Python/dynload_shlib.c.orig 2011-12-05 00:00:00.000000000 +0100
+++ Python-2.7.1/Python/dynload_shlib.c 2011-12-05 00:02:51.000000000 +0100
@@ -84,6 +84,15 @@
PyOS_snprintf(funcname, sizeof(funcname),
LEAD_UNDERSCORE "init%.200s", shortname);
+ /* On IOS, dlopen crash as soon as we try to open one of our library.
+ * Instead, we have done a redirection of linking to convert our .so into a
+ * .a. Then the main executable is linked with theses symbol. So, instead
+ * of trying to dlopen, directly do the dlsym.
+ * -- Mathieu
+ */
+ return (dl_funcptr) dlsym(RTLD_MAIN_ONLY, funcname);
+
+#if 0
if (fp != NULL) {
int i;
struct stat statb;
@@ -140,4 +149,5 @@
handles[nhandles++].handle = handle;
p = (dl_funcptr) dlsym(handle, funcname);
return p;
+#endif
}

View file

@ -0,0 +1,24 @@
Index: Modules/posixmodule.c
===================================================================
--- Modules/posixmodule.c (revision 52827)
+++ Modules/posixmodule.c (working copy)
@@ -314,7 +314,7 @@
#endif
/* Return a dictionary corresponding to the POSIX environment table */
-#ifdef WITH_NEXT_FRAMEWORK
+#ifdef __APPLE__
/* On Darwin/MacOSX a shared library or framework has no access to
** environ directly, we must obtain it with _NSGetEnviron().
*/
@@ -332,7 +332,7 @@
d = PyDict_New();
if (d == NULL)
return NULL;
-#ifdef WITH_NEXT_FRAMEWORK
+#ifdef __APPLE__
if (environ == NULL)
environ = *_NSGetEnviron();
#endif

View file

@ -0,0 +1,159 @@
--- Python2.7-old/pyconfig.h 2013-08-26 19:26:05.000000000 +0200
+++ Python2.7-new/pyconfig.h 2013-08-27 00:11:06.000000000 +0200
@@ -72,7 +72,7 @@
/* #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE */
/* Define to 1 if you have the `bind_textdomain_codeset' function. */
-#define HAVE_BIND_TEXTDOMAIN_CODESET 1
+/* #undef HAVE_BIND_TEXTDOMAIN_CODESET */
/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */
/* #undef HAVE_BLUETOOTH_BLUETOOTH_H */
@@ -218,7 +218,7 @@
/* #undef HAVE_FDATASYNC */
/* Define to 1 if you have the `finite' function. */
-#define HAVE_FINITE 1
+/* #undef HAVE_FINITE */
/* Define to 1 if you have the `flock' function. */
#define HAVE_FLOCK 1
@@ -233,7 +233,7 @@
#define HAVE_FPATHCONF 1
/* Define to 1 if you have the `fseek64' function. */
-#define HAVE_FSEEK64 1
+/* #undef HAVE_FSEEK64 */
/* Define to 1 if you have the `fseeko' function. */
#define HAVE_FSEEKO 1
@@ -245,7 +245,7 @@
#define HAVE_FSYNC 1
/* Define to 1 if you have the `ftell64' function. */
-#define HAVE_FTELL64 1
+/* #undef HAVE_FTELL64 */
/* Define to 1 if you have the `ftello' function. */
#define HAVE_FTELLO 1
@@ -260,7 +260,7 @@
#define HAVE_GAI_STRERROR 1
/* Define to 1 if you have the `gamma' function. */
-#define HAVE_GAMMA 1
+/* #undef HAVE_GAMMA */
/* Define if we can use gcc inline assembler to get and set x87 control word
*/
@@ -279,10 +279,10 @@
#define HAVE_GETGROUPS 1
/* Define to 1 if you have the `gethostbyname' function. */
-/* #undef HAVE_GETHOSTBYNAME */
+#define HAVE_GETHOSTBYNAME 1
/* Define this if you have some version of gethostbyname_r() */
-#define HAVE_GETHOSTBYNAME_R 1
+/* #undef HAVE_GETHOSTBYNAME_R */
/* Define this if you have the 3-arg version of gethostbyname_r(). */
/* #undef HAVE_GETHOSTBYNAME_R_3_ARG */
@@ -291,7 +291,7 @@
/* #undef HAVE_GETHOSTBYNAME_R_5_ARG */
/* Define this if you have the 6-arg version of gethostbyname_r(). */
-#define HAVE_GETHOSTBYNAME_R_6_ARG 1
+/* #undef HAVE_GETHOSTBYNAME_R_6_ARG */
/* Define to 1 if you have the `getitimer' function. */
#define HAVE_GETITIMER 1
@@ -327,19 +327,19 @@
#define HAVE_GETPWENT 1
/* Define to 1 if you have the `getresgid' function. */
-#define HAVE_GETRESGID 1
+/* #undef HAVE_GETRESGID */
/* Define to 1 if you have the `getresuid' function. */
-#define HAVE_GETRESUID 1
+/* #undef HAVE_GETRESUID */
/* Define to 1 if you have the `getsid' function. */
#define HAVE_GETSID 1
/* Define to 1 if you have the `getspent' function. */
-#define HAVE_GETSPENT 1
+/* #undef HAVE_GETSPENT */
/* Define to 1 if you have the `getspnam' function. */
-#define HAVE_GETSPNAM 1
+/* #undef HAVE_GETSPNAM */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
@@ -465,7 +465,7 @@
#define HAVE_MKTIME 1
/* Define to 1 if you have the `mremap' function. */
-#define HAVE_MREMAP 1
+/* #undef HAVE_MREMAP */
/* Define to 1 if you have the <ncurses.h> header file. */
/* #undef HAVE_NCURSES_H */
@@ -492,7 +492,7 @@
#define HAVE_PAUSE 1
/* Define to 1 if you have the `plock' function. */
-#define HAVE_PLOCK 1
+/* #undef HAVE_PLOCK */
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
@@ -567,7 +567,7 @@
#define HAVE_SEM_OPEN 1
/* Define to 1 if you have the `sem_timedwait' function. */
-#define HAVE_SEM_TIMEDWAIT 1
+/* #undef HAVE_SEM_TIMEDWAIT */
/* Define to 1 if you have the `sem_unlink' function. */
#define HAVE_SEM_UNLINK 1
@@ -600,10 +600,10 @@
#define HAVE_SETREGID 1
/* Define to 1 if you have the `setresgid' function. */
-#define HAVE_SETRESGID 1
+/* #undef HAVE_SETRESGID */
/* Define to 1 if you have the `setresuid' function. */
-#define HAVE_SETRESUID 1
+/* #undef HAVE_SETRESUID */
/* Define to 1 if you have the `setreuid' function. */
#define HAVE_SETREUID 1
@@ -829,7 +829,7 @@
#define HAVE_TMPNAM 1
/* Define to 1 if you have the `tmpnam_r' function. */
-#define HAVE_TMPNAM_R 1
+/* #undef HAVE_TMPNAM_R */
/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
`HAVE_STRUCT_TM_TM_ZONE' instead. */
@@ -894,7 +894,7 @@
#define HAVE_ZLIB_COPY 1
/* Define to 1 if you have the `_getpty' function. */
-#define HAVE__GETPTY 1
+/* #undef HAVE__GETPTY */
/* Define if you are using Mach cthreads directly under /include */
/* #undef HURD_C_THREADS */
@@ -1245,5 +1245,4 @@
#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
#endif
-#endif /*Py_PYCONFIG_H*/
-
+#endif /*Py_PYCONFIG_H*/
\ No newline at end of file

View file

@ -0,0 +1,11 @@
--- Python-2.7.1/setup.py.orig 2013-10-25 17:28:03.000000000 +0200
+++ Python-2.7.1/setup.py 2013-10-25 17:27:56.000000000 +0200
@@ -87,7 +87,7 @@
f = os.path.join(sysroot, dir[1:], filename)
if os.path.exists(f):
- return [dir]
+ return [os.path.dirname(f)]
# Not found anywhere
return None

View file

@ -0,0 +1,17 @@
diff -Naur Python-2.7.1.orig/Include/pyport.h Python-2.7.1/Include/pyport.h
--- Python-2.7.1.orig/Include/pyport.h 2010-09-14 18:10:22.000000000 +0200
+++ Python-2.7.1/Include/pyport.h 2011-05-13 12:24:53.000000000 +0200
@@ -186,9 +186,11 @@
#endif
/* Largest positive value of type Py_ssize_t. */
-#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
+//#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
/* Smallest negative value of type Py_ssize_t. */
-#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
+//#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
+#define PY_SSIZE_T_MAX TMP_MAX
+#define PY_SSIZE_T_MIN -TMP_MAX
#if SIZEOF_PID_T > SIZEOF_LONG
# error "Python doesn't support sizeof(pid_t) > sizeof(long)"

View file

@ -0,0 +1,25 @@
--- Python-2.7.1/Modules/_sqlite/module.c.orig 2012-10-28 02:30:58.000000000 +0200
+++ Python-2.7.1/Modules/_sqlite/module.c 2012-10-28 02:28:12.000000000 +0200
@@ -28,6 +28,9 @@
#include "prepare_protocol.h"
#include "microprotocols.h"
#include "row.h"
+#ifndef MODULE_NAME
+#define MODULE_NAME "_sqlite3"
+#endif
#if SQLITE_VERSION_NUMBER >= 3003003
#define HAVE_SHARED_CACHE
--- Python-2.7.1/Modules/_sqlite/sqlitecompat.h.orig 2012-10-28 02:30:53.000000000 +0200
+++ Python-2.7.1/Modules/_sqlite/sqlitecompat.h 2012-10-28 02:28:14.000000000 +0200
@@ -26,6 +26,10 @@
#ifndef PYSQLITE_COMPAT_H
#define PYSQLITE_COMPAT_H
+#ifndef MODULE_NAME
+#define MODULE_NAME "_sqlite3"
+#endif
+
/* define Py_ssize_t for pre-2.5 versions of Python */
#if PY_VERSION_HEX < 0x02050000

View file

@ -0,0 +1,138 @@
diff -Naur Python-2.7-old/Makefile.pre.in Python-2.7-new/Makefile.pre.in
--- Python-2.7-old/Makefile.pre.in 2010-04-11 17:10:46.000000000 -0700
+++ Python-2.7-new/Makefile.pre.in 2010-07-09 13:40:47.000000000 -0700
@@ -179,6 +179,7 @@
PYTHON= python$(EXE)
BUILDPYTHON= python$(BUILDEXE)
+HOSTPYTHON= ./$(BUILDPYTHON)
# The task to run while instrument when building the profile-opt target
PROFILE_TASK= $(srcdir)/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck
@@ -212,6 +213,8 @@
# Parser
PGEN= Parser/pgen$(EXE)
+HOSTPGEN= $(PGEN)
+
POBJS= \
Parser/acceler.o \
Parser/grammar1.o \
@@ -404,8 +407,8 @@
# Build the shared modules
sharedmods: $(BUILDPYTHON)
@case $$MAKEFLAGS in \
- *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py -q build;; \
- *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' ./$(BUILDPYTHON) -E $(srcdir)/setup.py build;; \
+ *s*) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(HOSTPYTHON) -E $(srcdir)/setup.py -q build;; \
+ *) $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' PYTHONXCPREFIX='$(DESTDIR)$(prefix)' $(HOSTPYTHON) -E $(srcdir)/setup.py build;; \
esac
# Build static library
@@ -538,7 +541,7 @@
$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT)
-@$(INSTALL) -d Include
- -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
+ -$(HOSTPGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C)
$(PGEN): $(PGENOBJS)
$(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
@@ -919,26 +922,26 @@
done; \
done
$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+ $(HOSTPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
$(DESTDIR)$(LIBDEST)
- PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
+ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
+ $(HOSTPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST) -f \
-x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \
$(DESTDIR)$(LIBDEST)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
+ $(HOSTPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
+ $(HOSTPYTHON) -Wi -t -O $(DESTDIR)$(LIBDEST)/compileall.py \
-d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
- ./$(BUILDPYTHON) -Wi -t -c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"
+ $(HOSTPYTHON) -Wi -t -c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"
# Create the PLATDIR source directory, if one wasn't distributed..
$(srcdir)/Lib/$(PLATDIR):
@@ -1042,8 +1045,10 @@
# Install the dynamically loadable modules
# This goes into $(exec_prefix)
-sharedinstall: sharedmods
- $(RUNSHARED) ./$(BUILDPYTHON) -E $(srcdir)/setup.py install \
+sharedinstall: sharedmods
+ CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
+ $(RUNSHARED) $(HOSTPYTHON) -E $(srcdir)/setup.py install \
+ --skip-build \
--prefix=$(prefix) \
--install-scripts=$(BINDIR) \
--install-platlib=$(DESTSHARED) \
diff -Naur Python-2.7-old/setup.py Python-2.7-new/setup.py
--- Python-2.7-old/setup.py 2010-06-27 05:36:16.000000000 -0700
+++ Python-2.7-new/setup.py 2010-07-09 13:54:29.000000000 -0700
@@ -23,6 +23,10 @@
# This global variable is used to hold the list of modules to be disabled.
disabled_module_list = []
+# _ctypes fails to cross-compile due to the libffi configure script.
+if os.environ.has_key('PYTHONXCPREFIX'):
+ disabled_module_list.append('_ctypes')
+
def add_dir_to_list(dirlist, dir):
"""Add the directory 'dir' to the list 'dirlist' (at the front) if
1) 'dir' is not already in 'dirlist'
@@ -278,6 +282,14 @@
(ext.name, sys.exc_info()[1]))
self.failed.append(ext.name)
return
+
+ # Inport check will not work when cross-compiling.
+ if os.environ.has_key('PYTHONXCPREFIX'):
+ self.announce(
+ 'WARNING: skipping inport check for cross-compiled: "%s"' %
+ ext.name)
+ return
+
# Workaround for Mac OS X: The Carbon-based modules cannot be
# reliably imported into a command-line Python
if 'Carbon' in ext.extra_link_args:
--- Python-2.7Orig/configure 2011-04-29 22:30:59.231331437 +1000
+++ Python-2.7/configure 2010-05-29 01:28:47.000000000 +1000
@@ -13517,7 +13517,7 @@
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
- ac_cv_have_long_long_format=no
+ ac_cv_have_long_long_format="cross -- assuming yes"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -13569,7 +13569,7 @@
$as_echo "$ac_cv_have_long_long_format" >&6; }
fi
-if test "$ac_cv_have_long_long_format" = yes
+if test "$ac_cv_have_long_long_format" != no
then
$as_echo "#define PY_FORMAT_LONG_LONG \"ll\"" >>confdefs.h

307
toolchain.py Normal file
View file

@ -0,0 +1,307 @@
"""
Tool for compiling iOS toolchain
================================
This tool intend to replace all the previous tools/ in shell script.
"""
import sys
from sys import stdout
from os.path import join, dirname, realpath, exists, isdir, basename
from os import listdir, unlink, makedirs, environ
import zipfile
import tarfile
import importlib
import sh
import shutil
try:
from urllib.request import FancyURLopener
except ImportError:
from urllib import FancyURLopener
def shprint(command, *args, **kwargs):
kwargs["_iter"] = True
kwargs["_out_bufsize"] = 1
#kwargs["_err_to_out"] = True
for line in command(*args, **kwargs):
stdout.write(line)
class ChromeDownloader(FancyURLopener):
version = (
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36')
urlretrieve = ChromeDownloader().retrieve
class Context(object):
env = environ.copy()
root_dir = None
cache_dir = None
build_dir = None
dist_dir = None
install_dir = None
ccache = None
cython = None
sdkver = None
sdksimver = None
def __init__(self):
super(Context, self).__init__()
ok = True
sdks = sh.xcodebuild("-showsdks").splitlines()
# get the latest iphoneos
iphoneos = [x for x in sdks if "iphoneos" in x]
if not iphoneos:
print("No iphone SDK installed")
ok = False
else:
iphoneos = iphoneos[0].split()[-1]
self.sdkver = iphoneos
# get the latest iphonesimulator version
iphonesim = [x for x in sdks if "iphonesimulator" in x]
if not iphoneos:
ok = False
print("Error: No iphonesimulator SDK installed")
else:
iphonesim = iphonesim[0].split()[-1]
self.sdksimver = iphonesim
# get the path for Developer
self.devroot = "{}/Platforms/iPhoneOS.platform/Developer".format(
sh.xcode_select("-print-path").strip())
# path to the iOS SDK
self.iossdkroot = "{}/SDKs.iPhoneOS{}.sdk".format(
self.devroot, self.sdkver)
# root of the toolchain
self.root_dir = realpath(dirname(__file__))
self.build_dir = "{}/build".format(self.root_dir)
self.cache_dir = "{}/.cache".format(self.root_dir)
self.dist_dir = "{}/dist".format(self.root_dir)
self.install_dir = "{}/dist/root".format(self.root_dir)
self.archs = ("i386", "armv7", "armv7s", "arm64")
# path to some tools
self.ccache = sh.which("ccache")
if not self.ccache:
print("ccache is missing, the build will not be optimized in the future.")
for cython_fn in ("cython-2.7", "cython"):
cython = sh.which(cython_fn)
if cython:
self.cython = cython
break
if not self.cython:
ok = False
print("Missing requirement: cython is not installed")
# check the basic tools
for tool in ("pkg-config", "autoconf", "automake", "libtool", "hg"):
if not sh.which(tool):
print("Missing requirement: {} is not installed".format(
tool))
if not ok:
sys.exit(1)
ensure_dir(self.root_dir)
ensure_dir(self.build_dir)
ensure_dir(self.cache_dir)
ensure_dir(self.dist_dir)
ensure_dir(self.install_dir)
class Recipe(object):
version = None
url = None
# API available for recipes
def download_file(self, url, filename, cwd=None):
"""
Download an `url` to `outfn`
"""
def report_hook(index, blksize, size):
if size <= 0:
progression = '{0} bytes'.format(index * blksize)
else:
progression = '{0:.2f}%'.format(
index * blksize * 100. / float(size))
stdout.write('- Download {}\r'.format(progression))
stdout.flush()
if cwd:
filename = join(cwd, filename)
if exists(filename):
unlink(filename)
print('Downloading {0}'.format(url))
urlretrieve(url, filename, report_hook)
return filename
def extract_file(self, filename, cwd):
"""
Extract the `filename` into the directory `cwd`.
"""
print("Extract {} into {}".format(filename, cwd))
if filename.endswith(".tgz") or filename.endswith(".tar.gz"):
shprint(sh.tar, "-C", cwd, "-xvzf", filename)
elif filename.endswith(".tbz2") or filename.endswith(".tar.bz2"):
shprint(sh.tar, "-C", cwd, "-xvjf", filename)
elif filename.endswith(".zip"):
zf = zipfile.ZipFile(filename)
zf.extractall(path=cwd)
zf.close()
else:
print("Error: cannot extract, unreconized extension for {}".format(
filename))
raise Exception()
def get_archive_rootdir(self, filename):
if filename.endswith(".tgz") or filename.endswith(".tar.gz") or \
filename.endswith(".tbz2") or filename.endswith(".tar.bz2"):
archive = tarfile.open(filename)
root = archive.next().path.split("/")
return root[0]
else:
print("Error: cannot detect root direction")
print("Unrecognized extension for {}".format(filename))
raise Exception()
def apply_patch(self, filename):
"""
Apply a patch from the current recipe directory into the current
build directory.
"""
print("Apply patch {}".format(filename))
filename = join(self.recipe_dir, filename)
sh.patch("-t", "-d", self.build_dir, "-p1", "-i", filename)
def copy_file(self, filename, dest):
filename = join(self.recipe_dir, filename)
dest = join(self.build_dir, dest)
shutil.copy(filename, dest)
def has_marker(self, marker):
"""
Return True if the current build directory has the marker set
"""
return exists(join(self.build_dir, ".{}".format(marker)))
def set_marker(self, marker):
"""
Set a marker info the current build directory
"""
with open(join(self.build_dir, ".{}".format(marker)), "w") as fd:
fd.write("ok")
def marker(self, marker):
"""
Return a context that will be executed only if the marker has been set
"""
@property
def name(self):
modname = self.__class__.__module__
return modname.split(".", 1)[-1]
@property
def archive_fn(self):
if hasattr(self, "ext"):
ext = self.ext
else:
ext = basename(self.url).split(".", 1)[-1]
fn = "{}/{}.{}".format(
self.ctx.cache_dir,
self.name, ext)
return fn
# Public Recipe API to be subclassed if needed
def execute(self):
print("Download {}".format(self.name))
self.download()
print("Extract {}".format(self.name))
self.extract()
print("Build {}".format(self.name))
self.build_all()
def download(self):
fn = self.archive_fn
if not exists(fn):
self.download_file(self.url.format(version=self.version), fn)
def extract(self):
# recipe tmp directory
archive_root = self.get_archive_rootdir(self.archive_fn)
for arch in self.ctx.archs:
print("Extract {} for {}".format(self.name, arch))
build_dir = join(self.ctx.build_dir, arch)
if exists(join(build_dir, archive_root)):
continue
ensure_dir(build_dir)
self.extract_file(self.archive_fn, build_dir)
def build_all(self):
archive_root = self.get_archive_rootdir(self.archive_fn)
for arch in self.ctx.archs:
self.build_dir = join(self.ctx.build_dir, arch, archive_root)
self.prebuild_arch(arch)
self.build_arch(arch)
self.postbuild_arch(arch)
def prebuild_arch(self, arch):
print("Prebuild {} for {}".format(self.name, arch))
prebuild = "prebuild_{}".format(arch)
if hasattr(self, prebuild):
getattr(self, prebuild)()
def build_arch(self, arch):
print("Build {} for {}".format(self.name, arch))
build = "build_{}".format(arch)
if hasattr(self, build):
getattr(self, build)()
def postbuild_arch(self, arch):
print("Postbuild {} for {}".format(self.name, arch))
postbuild = "postbuild_{}".format(arch)
if hasattr(self, postbuild):
getattr(self, postbuild)()
def list_recipes():
recipes_dir = join(dirname(__file__), "recipes")
for name in listdir(recipes_dir):
fn = join(recipes_dir, name)
if isdir(fn):
yield name
def compile_recipe(name, ctx):
mod = importlib.import_module("recipes.{}".format(name))
recipe = mod.recipe
recipe.recipe_dir = join(ctx.root_dir, "recipes", name)
recipe.ctx = ctx
recipe.execute()
def ensure_dir(filename):
if not exists(filename):
makedirs(filename)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='Compile Python and others extensions for iOS')
args = parser.parse_args()
ctx = Context()
print list(list_recipes())
compile_recipe("hostpython", ctx)