Skip to content
This repository was archived by the owner on Mar 30, 2019. It is now read-only.

Commit e4c004f

Browse files
committed
Added build phase for Python.
1 parent 5e9cb1d commit e4c004f

13 files changed

+594
-18
lines changed

Makefile

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1+
PROJECTDIR=$(shell pwd)
2+
13
# iOS Build variables.
2-
SDKVER=$(xcodebuild -showsdks | fgrep "iphoneos" | tail -n 1 | awk '{print $2}')
3-
DEVROOT=$(xcode-select -print-path)/Platforms/iPhoneOS.platform/Developer
4-
IOSSDKROOT=$DEVROOT/SDKs/iPhoneOS$(SDKVER).sdk
4+
SDKDESCRIPTION=$(shell xcodebuild -showsdks | fgrep "iphoneos" | tail -n 1)
5+
SDKVER=$(word 2, $(SDKDESCRIPTION))
6+
DEVROOT=$(shell xcode-select -print-path)/Platforms/iPhoneOS.platform/Developer
7+
IOSSDKROOT=$(DEVROOT)/SDKs/iPhoneOS$(SDKVER).sdk
8+
9+
OSX_SDK_ROOT=$(shell xcrun --sdk macosx --show-sdk-path)
510

611
# Version of packages that will be compiled by this meta-package
712
PYTHON_VERSION=2.7.1
813
FFI_VERSION=3.0.13
914

10-
all: working-dirs build/ffi.framework
15+
# ARM build flags
16+
ARM_CC=$(shell xcrun -find -sdk iphoneos clang)
17+
ARM_AR=$(shell xcrun -find -sdk iphoneos ar)
18+
ARM_LD=$(shell xcrun -find -sdk iphoneos ld)
19+
20+
ARM_CFLAGS=-arch armv7 -pipe -no-cpp-precomp -isysroot $(IOSSDKROOT) -miphoneos-version-min=$(SDKVER)
21+
ARM_LDFLAGS=-arch armv7 -isysroot $(IOSSDKROOT) -miphoneos-version-min=$(SDKVER)
22+
23+
24+
all: working-dirs build/ffi.framework build/Python.framework
1125

1226
# Clean all builds
1327
clean:
@@ -50,20 +64,88 @@ src/libffi-$(FFI_VERSION): downloads/libffi-$(FFI_VERSION).tar.gz
5064
tar xvf downloads/libffi-$(FFI_VERSION).tar.gz
5165
mv libffi-$(FFI_VERSION) src
5266

53-
# Patch libffi source with iOS patches
54-
# Produce a dummy "patches-applied" file to mark that this has happened.
55-
src/libffi-$(FFI_VERSION)/patches-applied: src/libffi-$(FFI_VERSION)
67+
# Patch and build the framework
68+
build/ffi.framework: src/libffi-$(FFI_VERSION)
5669
cd src/libffi-$(FFI_VERSION) && patch -p1 -N < ../../patch/libffi/$(FFI_VERSION)/ffi-sysv.S.patch
57-
cd src/libffi-$(FFI_VERSION) && patch -p1 -N < ../../patch/libffi/$(FFI_VERSION)/project.pbxproj.patch | tee patches-applied
58-
59-
# Generate iOS specific source and headers
60-
src/libffi-$(FFI_VERSION)/ios/include/ffi.h: src/libffi-$(FFI_VERSION)/patches-applied
70+
cd src/libffi-$(FFI_VERSION) && patch -p1 -N < ../../patch/libffi/$(FFI_VERSION)/project.pbxproj.patch
6171
cd src/libffi-$(FFI_VERSION) && python generate-ios-source-and-headers.py
62-
63-
# Build the iOS project
64-
src/libffi-$(FFI_VERSION)/build/Release-universal/ffi.framework: src/libffi-$(FFI_VERSION)/ios/include/ffi.h
6572
cd src/libffi-$(FFI_VERSION) && xcodebuild -project libffi.xcodeproj -target "Framework" -configuration Release -sdk iphoneos$(SDKVER) OTHER_CFLAGS="-no-integrated-as"
66-
67-
# Collate the libffi project
68-
build/ffi.framework: src/libffi-$(FFI_VERSION)/build/Release-universal/ffi.framework
6973
cp -a src/libffi-$(FFI_VERSION)/build/Release-universal/ffi.framework build
74+
75+
###########################################################################
76+
# Python
77+
###########################################################################
78+
79+
# Clean the Python project
80+
clean-Python:
81+
rm -rf src/Python-$(PYTHON_VERSION)
82+
rm -rf build/Python.framework
83+
84+
# Down original Python source code archive.
85+
downloads/Python-$(PYTHON_VERSION).tar.bz2:
86+
curl -L https://www.python.org/ftp/python/$(PYTHON_VERSION)/Python-$(PYTHON_VERSION).tar.bz2 > downloads/Python-$(PYTHON_VERSION).tar.bz2
87+
88+
# Unpack Python source archive into src working directory
89+
src/Python-$(PYTHON_VERSION): downloads/Python-$(PYTHON_VERSION).tar.bz2
90+
tar xvf downloads/Python-$(PYTHON_VERSION).tar.bz2
91+
mv Python-$(PYTHON_VERSION) src
92+
93+
# Patch Python source with iOS patches
94+
# Produce a dummy "patches-applied" file to mark that this has happened.
95+
src/Python-$(PYTHON_VERSION)/build_simulator: src/Python-$(PYTHON_VERSION)
96+
# Apply patches
97+
cp patch/Python/$(PYTHON_VERSION)/ModulesSetup src/Python-$(PYTHON_VERSION)/Modules/Setup.local
98+
cp patch/Python/$(PYTHON_VERSION)/_scproxy.py src/Python-$(PYTHON_VERSION)/Lib/_scproxy.py
99+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/dynload.patch
100+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/ssize-t-max.patch
101+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/static-_sqlite3.patch
102+
# Configure and make the x86 (simulator) build
103+
cd src/Python-$(PYTHON_VERSION) && ./configure CC="clang -Qunused-arguments -fcolor-diagnostics" LDFLAGS="-lsqlite3 -L../../build/ffi.framework" CFLAGS="-I../../build/ffi.framework/Headers --sysroot=$(OSX_SDK_ROOT)" --prefix=$(PROJECTDIR)/src/Python-$(PYTHON_VERSION)/build_simulator
104+
cd src/Python-$(PYTHON_VERSION) && make -j4 python.exe Parser/pgen libpython$(basename $(PYTHON_VERSION)).a install
105+
# Create the framework directory from the compiled resrouces
106+
mkdir -p build/Python.framework/Versions/$(basename $(PYTHON_VERSION))/
107+
cd build/Python.framework/Versions && ln -fs $(basename $(PYTHON_VERSION)) Current
108+
cp -r src/Python-$(PYTHON_VERSION)/build_simulator/include/python$(basename $(PYTHON_VERSION)) build/Python.framework/Versions/$(basename $(PYTHON_VERSION))/Headers
109+
cd build/Python.framework && ln -fs Versions/Current/Headers
110+
cp -r src/Python-$(PYTHON_VERSION)/build_simulator/lib/python$(basename $(PYTHON_VERSION)) build/Python.framework/Versions/$(basename $(PYTHON_VERSION))/Resources
111+
cd build/Python.framework && ln -fs Versions/Current/Resources
112+
# Temporarily move the x86 library into the framework dir to protect it from distclean
113+
mv src/Python-$(PYTHON_VERSION)/libpython$(basename $(PYTHON_VERSION)).a build/Python.framework
114+
# Clean out all the x86 build data
115+
cd src/Python-$(PYTHON_VERSION) && make distclean
116+
# Restore the x86 library
117+
mv build/Python.framework/libpython$(basename $(PYTHON_VERSION)).a src/Python-$(PYTHON_VERSION)/build_simulator
118+
119+
src/Python-$(PYTHON_VERSION)/build_iphone: src/Python-$(PYTHON_VERSION)/build_simulator
120+
# Apply extra patches for iOS native build
121+
cp patch/Python/$(PYTHON_VERSION)/ModulesSetup src/Python-$(PYTHON_VERSION)/Modules/Setup.local
122+
cat patch/Python/$(PYTHON_VERSION)/ModulesSetup.mobile >> src/Python-$(PYTHON_VERSION)/Modules/Setup.local
123+
cp patch/Python/$(PYTHON_VERSION)/_scproxy.py src/Python-$(PYTHON_VERSION)/Lib/_scproxy.py
124+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/xcompile.patch
125+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/setuppath.patch
126+
# Configure and build iOS library
127+
cd src/Python-$(PYTHON_VERSION) && ./configure CC="$(ARM_CC)" LD="$(ARM_LD)" CFLAGS="$(ARM_CFLAGS) -I../../build/ffi.framework/Headers" LDFLAGS="$(ARM_LDFLAGS) -L../../build/ffi.framework/ -lsqlite3 -undefined dynamic_lookup" --without-pymalloc --disable-toolbox-glue --host=armv7-apple-darwin --prefix=/python --without-doc-strings
128+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/ctypes_duplicate.patch
129+
cd src/Python-$(PYTHON_VERSION) && patch -p1 -N < ../../patch/Python/$(PYTHON_VERSION)/pyconfig.patch
130+
cd src/Python-$(PYTHON_VERSION) && make -j4 libpython$(basename $(PYTHON_VERSION)).a
131+
132+
build/Python.framework: src/Python-$(PYTHON_VERSION)/build_iphone
133+
xcrun lipo -create -output build/Python.framework/Versions/Current/libpython.a src/Python-$(PYTHON_VERSION)/build_simulator/libpython$(basename $(PYTHON_VERSION)).a src/Python-$(PYTHON_VERSION)/libpython$(basename $(PYTHON_VERSION)).a
134+
cd build/Python.framework && ln -fs Versions/Current/libpython.a
135+
136+
env:
137+
echo "SDKDESCRIPTION" $(SDKDESCRIPTION)
138+
echo "SDKVER" $(SDKVER)
139+
echo "DEVROOT" $(DEVROOT)
140+
echo "IOSSDKROOT" $(IOSSDKROOT)
141+
echo "OSX_SDK_ROOT" $(OSX_SDK_ROOT)
142+
echo "PYTHON_VERSION" $(PYTHON_VERSION)
143+
echo "FFI_VERSION" $(FFI_VERSION)
144+
echo "ARM_CC" $(ARM_CC)
145+
echo "ARM_AR" $(ARM_AR)
146+
echo "ARM_LD" $(ARM_LD)
147+
echo "ARM_CFLAGS" $(ARM_CFLAGS)
148+
echo "ARM_LDFLAGS" $(ARM_LDFLAGS)
149+
150+
151+
# build/Python.framework: src/Python-$(PYTHON_VERSION)/hostpython

README.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ Python.framework
22
================
33

44
This is a meta-package for building a version of Python that can be embedded
5-
into an iOS project.
5+
into an iOS project. It works by downloading, patching, and *then* building
6+
a static libPython.a, and packaging it in iOS Framework format.
67

78
Quickstart
89
----------

patch/Python/2.7.1/ModulesSetup

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
posix posixmodule.c # posix (UNIX) system calls
2+
errno errnomodule.c # posix (UNIX) errno values
3+
pwd pwdmodule.c # this is needed to find out the user's home dir
4+
# if $HOME is not set
5+
_sre _sre.c # Fredrik Lundh's new regular expressions
6+
_codecs _codecsmodule.c # access to the builtin codecs and codec registry
7+
zipimport zipimport.c
8+
_symtable symtablemodule.c
9+
array arraymodule.c # array objects
10+
cmath cmathmodule.c # -lm # complex math library functions
11+
math mathmodule.c # -lm # math library functions, e.g. sin()
12+
_struct _struct.c # binary structure packing/unpacking
13+
time timemodule.c # -lm # time operations and variables
14+
operator operator.c # operator.add() and similar goodies
15+
_weakref _weakref.c # basic weak reference support
16+
_random _randommodule.c # Random number generator
17+
_collections _collectionsmodule.c # Container types
18+
itertools itertoolsmodule.c # Functions creating iterators for efficient looping
19+
strop stropmodule.c # String manipulations
20+
_functools _functoolsmodule.c # Tools for working with functions and callable objects
21+
_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator
22+
datetime datetimemodule.c # date/time type
23+
_bisect _bisectmodule.c # Bisection algorithms
24+
fcntl fcntlmodule.c # fcntl(2) and ioctl(2)
25+
select selectmodule.c # select(2); not on ancient System V
26+
_socket socketmodule.c
27+
_md5 md5module.c md5.c
28+
_sha shamodule.c
29+
_sha256 sha256module.c
30+
_sha512 sha512module.c
31+
binascii binascii.c
32+
parser parsermodule.c
33+
cStringIO cStringIO.c
34+
cPickle cPickle.c
35+
zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
36+
xxsubtype xxsubtype.c
37+
unicodedata unicodedata.c # static Unicode character database
38+
39+
# Theses modules are used by Kivy inside other module
40+
# json in Settings, _io by zipfile...
41+
_json _json.c
42+
_io _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c
43+
_heapq _heapqmodule.c
44+
45+
# Special inclusion for sqlite3
46+
_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
47+
48+
# Include expat
49+
pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Ctypes
2+
_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c -I$(srcdir)/../../build/include/ffi

patch/Python/2.7.1/_scproxy.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'''
2+
Stub functions for _scproxy on iOS
3+
No proxy is supported yet.
4+
'''
5+
6+
def _get_proxy_settings():
7+
return {'exclude_simple': 1}
8+
9+
def _get_proxies():
10+
return {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--- Python2.7-old/Modules/_ctypes/cfield.c 2010-05-09 16:46:46.000000000 +0200
2+
+++ Python2.7-new/Modules/_ctypes/cfield.c 2013-08-27 00:21:15.000000000 +0200
3+
@@ -1747,24 +1747,6 @@
4+
} ffi_type;
5+
*/
6+
7+
-/* align and size are bogus for void, but they must not be zero */
8+
-ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
9+
-
10+
-ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 };
11+
-ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 };
12+
-
13+
-ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 };
14+
-ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 };
15+
-
16+
-ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 };
17+
-ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 };
18+
-
19+
-ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 };
20+
-ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 };
21+
-
22+
-ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT };
23+
-ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE };
24+
-
25+
#ifdef ffi_type_longdouble
26+
#undef ffi_type_longdouble
27+
#endif
28+
@@ -1772,6 +1754,4 @@
29+
ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN,
30+
FFI_TYPE_LONGDOUBLE };
31+
32+
-ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
33+
-
34+
/*---------------- EOF ----------------*/

patch/Python/2.7.1/dynload.patch

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--- Python-2.7.1/Python/dynload_shlib.c.orig 2011-12-05 00:00:00.000000000 +0100
2+
+++ Python-2.7.1/Python/dynload_shlib.c 2011-12-05 00:02:51.000000000 +0100
3+
@@ -84,6 +84,15 @@
4+
PyOS_snprintf(funcname, sizeof(funcname),
5+
LEAD_UNDERSCORE "init%.200s", shortname);
6+
7+
+ /* On IOS, dlopen crash as soon as we try to open one of our library.
8+
+ * Instead, we have done a redirection of linking to convert our .so into a
9+
+ * .a. Then the main executable is linked with theses symbol. So, instead
10+
+ * of trying to dlopen, directly do the dlsym.
11+
+ * -- Mathieu
12+
+ */
13+
+ return (dl_funcptr) dlsym(RTLD_MAIN_ONLY, funcname);
14+
+
15+
+#if 0
16+
if (fp != NULL) {
17+
int i;
18+
struct stat statb;
19+
@@ -140,4 +149,5 @@
20+
handles[nhandles++].handle = handle;
21+
p = (dl_funcptr) dlsym(handle, funcname);
22+
return p;
23+
+#endif
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Index: Modules/posixmodule.c
2+
===================================================================
3+
--- Modules/posixmodule.c (revision 52827)
4+
+++ Modules/posixmodule.c (working copy)
5+
@@ -314,7 +314,7 @@
6+
#endif
7+
8+
/* Return a dictionary corresponding to the POSIX environment table */
9+
-#ifdef WITH_NEXT_FRAMEWORK
10+
+#ifdef __APPLE__
11+
/* On Darwin/MacOSX a shared library or framework has no access to
12+
** environ directly, we must obtain it with _NSGetEnviron().
13+
*/
14+
@@ -332,7 +332,7 @@
15+
d = PyDict_New();
16+
if (d == NULL)
17+
return NULL;
18+
-#ifdef WITH_NEXT_FRAMEWORK
19+
+#ifdef __APPLE__
20+
if (environ == NULL)
21+
environ = *_NSGetEnviron();
22+
#endif
23+
24+

0 commit comments

Comments
 (0)