Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Kjell Wooding 2018-12-17 19:35:42 -08:00
commit e93c1cffa3
57 changed files with 1825 additions and 1718 deletions

1
.gitignore vendored
View file

@ -18,3 +18,4 @@ src/ios/iosbuild/
src/ios/ios.c src/ios/ios.c
*.DS_Store* *.DS_Store*
*-ios/ *-ios/
__pycache__

View file

@ -4,15 +4,17 @@ Kivy for iOS
This toolchain is designed to compile the necessary libraries for iOS to run This toolchain is designed to compile the necessary libraries for iOS to run
your application and manage the creation of the Xcode project. your application and manage the creation of the Xcode project.
Currently, we do not provide any binary distributions of this toolchain, but we We do not provide any binary distributions of this toolchain.
aim to. Until then, you do need to compile it at least once before creating You do need to compile it at least once before creating your Xcode project.
your Xcode project.
The toolchain supports: The toolchain supports:
- iPhone Simulator (x86 and x86_64) - iPhone Simulator (x86_64)
- iPhone / iOS (armv7 and arm64) - iPhone / iOS (armv7 and arm64)
You can select between Python 2.7 or Python 3.7 by specifying the recipes
`python2` or `python3` when building.
These recipes are not ported to the new toolchain yet: These recipes are not ported to the new toolchain yet:
- lxml - lxml
@ -23,7 +25,15 @@ Requirements
Currently, the toolchain requires a few tools for compilation. You will need: Currently, the toolchain requires a few tools for compilation. You will need:
#. Xcode 6 or above, with an iOS SDK and command line tools installed:: #. Ensure you have python3 installed - this is needed for toolchain.py::
brew install python
#. Ensure you have the right dependencies installed for python3::
pip3 install -r requirements.txt
#. Xcode 10 or above, with an iOS SDK and command line tools installed::
xcode-select --install xcode-select --install
@ -32,10 +42,10 @@ Currently, the toolchain requires a few tools for compilation. You will need:
brew install autoconf automake libtool pkg-config brew install autoconf automake libtool pkg-config
brew link libtool brew link libtool
#. Install Cython (0.23):: #. Install Cython (0.28.1)::
# pip method if available (sudo might be needed.) # pip method if available (sudo might be needed.)
pip install cython==0.23 pip install cython==0.28.1
Using the toolchain Using the toolchain
@ -49,26 +59,50 @@ contained in a `recipe`.
You can list the available recipes and their versions with:: You can list the available recipes and their versions with::
$ ./toolchain.py recipes $ ./toolchain.py recipes
audiostream master
click master
cymunk master
distribute 0.7.3
ffmpeg 2.6.3
ffpyplayer v3.2
flask master
freetype 2.5.5 freetype 2.5.5
hostpython 2.7.1 hostlibffi 3.2.1
hostpython2 2.7.1
hostpython3 3.7.1
ios master ios master
kivy ios-poly-arch itsdangerous master
jinja2 master
kivy 1.10.1
libffi 3.2.1 libffi 3.2.1
openssl 1.0.2e libjpeg v9a
libpng 1.6.26
markupsafe master
moodstocks 4.1.5
numpy 1.9.1
openssl 1.0.2k
photolibrary master
pil 2.8.2
plyer master
pycrypto 2.6.1
pykka 1.2.1
pyobjus master pyobjus master
python 2.7.1 python2 2.7.1
sdl2 iOS-improvements python3 3.7.1
pyyaml 3.11
sdl2 2.0.8
sdl2_image 2.0.0 sdl2_image 2.0.0
sdl2_mixer 2.0.0 sdl2_mixer 2.0.0
sdl2_ttf 2.0.12 sdl2_ttf 2.0.12
werkzeug master
Then, start the compilation with:: Then, start the compilation with::
$ ./toolchain.py build kivy $ ./toolchain.py build python3 kivy
You can build recipes at the same time by adding them as parameters:: You can build recipes at the same time by adding them as parameters::
$ ./toolchain.py build openssl kivy $ ./toolchain.py build python3 openssl kivy
Recipe builds can be removed via the clean command e.g.:: Recipe builds can be removed via the clean command e.g.::
@ -80,7 +114,7 @@ You can think of it as follows: the kivy recipe will compile everything
necessary for a minimal working version of Kivy. necessary for a minimal working version of Kivy.
Don't grab a coffee, just do diner. Compiling all the libraries for the first Don't grab a coffee, just do diner. Compiling all the libraries for the first
time, 4x over (remember, 4 archs, 2 per platforms by default) will take time. time, 3x over (remember, 3 archs, x86_64, armv7, arm64) will take time.
For a complete list of available commands, type:: For a complete list of available commands, type::
@ -148,7 +182,7 @@ Reducing the application size
If you would like to reduce the size of your distributed app, there are a few If you would like to reduce the size of your distributed app, there are a few
things you can do to achieve this: things you can do to achieve this:
#. Minimize the `build/python/lib/python27.zip`: this contains all the python #. Minimize the `build/pythonX/lib/pythonXX.zip`: this contains all the python
modules. You can edit the zip file and remove all the files you'll not use modules. You can edit the zip file and remove all the files you'll not use
(reduce encodings, remove xml, email...) (reduce encodings, remove xml, email...)
@ -157,18 +191,18 @@ things you can do to achieve this:
Python dynamic modules and will remove needed symbols. Python dynamic modules and will remove needed symbols.
#. By default, the iOS package compiles binaries for all processor #. By default, the iOS package compiles binaries for all processor
architectures, namely x86, x86_64, armv7 and arm64 as per the guidelines from architectures, namely x86_64, armv7 and arm64 as per the guidelines from
Apple. You can reduce the size of your ipa significantly by removing the Apple. You can reduce the size of your ipa significantly by removing the
x86 and x86_64 architectures as they are usually used only for the emulator. x86_64 architecture as they are used only for the emulator.
The procedure is to first compile/build all the host recipes as is:: The procedure is to first compile/build all the host recipes as is::
./toolchain.py build hostpython ./toolchain.py build hostpython3
Then build all the rest of the recipes using --arch=armv7 --arch=arm64 Then build all the rest of the recipes using --arch=armv7 --arch=arm64
arguments as follows:: arguments as follows::
./toolchain.py build kivy --arch=armv7 --arch=arm64 ./toolchain.py build python3 kivy --arch=armv7 --arch=arm64
Note that these packages will not run in the iOS emulators, so use them Note that these packages will not run in the iOS emulators, so use them
only for deployment. only for deployment.
@ -202,10 +236,15 @@ FAQ
Fatal error: "stdio.h" file not found Fatal error: "stdio.h" file not found
You need to install the Command line tools: `xcode-select --install` You need to install the Command line tools: `xcode-select --install`
You must build with bitcode disabled (Xcode setting ENABLE_BITCODE should be No). You must build with bitcode disabled (Xcode setting ENABLE_BITCODE should be No).
We don't support bitcode. You need to go to the project setting, and disable bitcode. We don't support bitcode. You need to go to the project setting, and disable bitcode.
You don't have permissions to run
It is due to invalid archs, search for them and check it. Maybe you
targetted a simulator but have only armv7/arm64. Maybe you want to target
your iPad but it as only x86_64.
Support Support
------- -------
@ -214,11 +253,10 @@ If you need assistance, you can ask for help on our mailing list:
* User Group : https://groups.google.com/group/kivy-users * User Group : https://groups.google.com/group/kivy-users
* Email : kivy-users@googlegroups.com * Email : kivy-users@googlegroups.com
We also have an IRC channel: We also have a Discord channel:
* Server : irc.freenode.net * Server : https://chat.kivy.org
* Port : 6667, 6697 (SSL only) * Channel : #support
* Channel : #kivy
Contributing Contributing
------------ ------------
@ -233,11 +271,10 @@ discussions about developing the Kivy framework and its sister projects:
* Dev Group : https://groups.google.com/group/kivy-dev * Dev Group : https://groups.google.com/group/kivy-dev
* Email : kivy-dev@googlegroups.com * Email : kivy-dev@googlegroups.com
IRC channel: Discord channel:
* Server : irc.freenode.net * Server : https://chat.kivy.org
* Port : 6667, 6697 (SSL only) * Channel : #dev
* Channel : #kivy-dev
License License
------- -------

View file

@ -0,0 +1,53 @@
"""
Author: Lawrence Du
E-mail: larrydu88@gmail.com
"""
from toolchain import CythonRecipe,shprint
import os
from os.path import join
import sh
class CymunkRecipe(CythonRecipe):
version = 'master'
url = 'https://github.com/tito/cymunk/archive/{version}.zip'
name = 'cymunk'
depends = ['hostpython']
cythonize = True
def build_arch(self, arch):
"""
Override build.arch to avoid calling setup.py here (Call it in
install() instead).
"""
self.cythonize_build()
self.biglink()
def install(self):
"""
Do the equivalent of
python setup.py build_ext install
while setting the proper environment variables
"""
arch = list(self.filtered_archs)[0]
build_env = self.get_recipe_env(arch)
hostpython = sh.Command(self.ctx.hostpython)
subdir_path = self.get_build_dir(arch.arch)
setup_path = join(subdir_path,"setup.py")
dest_dir = join (self.ctx.dist_dir, "root", "python")
build_env['PYTHONPATH'] = join(dest_dir, 'lib', 'python2.7', 'site-packages')
#Note: Throws error if PATH is not set. I am not sure if this will cause problems
# in other architectures.
build_env['PATH']= os.environ.get('PATH')
shprint(hostpython,
setup_path,
"build_ext",
#"--compiler=mingw32", #note: throws clang error
"install",
_env=build_env)
recipe = CymunkRecipe()

View file

@ -1,5 +1,6 @@
from toolchain import Recipe, shprint from toolchain import Recipe, shprint
import sh import sh
from os.path import exists
class LibffiRecipe(Recipe): class LibffiRecipe(Recipe):
@ -31,22 +32,30 @@ class LibffiRecipe(Recipe):
self.apply_patch("public_include.patch") self.apply_patch("public_include.patch")
self.apply_patch("staticlib.patch") self.apply_patch("staticlib.patch")
self.apply_patch("staticlib2.patch") self.apply_patch("staticlib2.patch")
self.apply_patch("libffi-xcode10.patch")
self.set_marker("patched") self.set_marker("patched")
def build_arch(self, arch): def build_arch(self, arch):
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, if exists("generate-darwin-source-and-headers.py"):
shprint(
sh.mv,
"generate-darwin-source-and-headers.py",
"_generate-darwin-source-and-headers.py")
shprint(sh.touch, "generate-darwin-source-and-headers.py")
python27 = sh.Command("python2.7")
shprint(python27, "_generate-darwin-source-and-headers.py", "--only-osx")
shprint(sh.xcodebuild,
self.ctx.concurrent_xcodebuild,
"ONLY_ACTIVE_ARCH=NO", "ONLY_ACTIVE_ARCH=NO",
"ARCHS={}".format(arch.arch), "ARCHS={}".format(arch.arch),
"DSTROOT={}/hostlibffi".format(self.ctx.dist_dir),
"-sdk", "macosx", "-sdk", "macosx",
"install", "installhdrs", "clean", "build", "installhdrs", "install",
"-project", "libffi.xcodeproj", "-project", "libffi.xcodeproj",
"-target", "libffi-Mac", "-scheme", "libffi-Mac",
"-configuration", "Release", "-configuration", "Release")
"DSTROOT={}/hostlibffi".format(self.ctx.dist_dir))
def postbuild_arch(self, arch): def postbuild_arch(self, arch):
pass pass
recipe = LibffiRecipe() recipe = LibffiRecipe()

View file

@ -0,0 +1,391 @@
--- libffi-3.2.1.old/generate-darwin-source-and-headers.py 2018-10-26 17:08:07.000000000 +0200
+++ libffi-3.2.1/generate-darwin-source-and-headers.py 2018-10-26 17:08:50.000000000 +0200
@@ -174,23 +174,23 @@
if generate_ios:
make_tramp()
- copy_src_platform_files(simulator_platform)
+ #copy_src_platform_files(simulator_platform)
copy_src_platform_files(simulator64_platform)
copy_src_platform_files(device_platform)
copy_src_platform_files(device64_platform)
if generate_osx:
- copy_src_platform_files(desktop32_platform)
+ #copy_src_platform_files(desktop32_platform)
copy_src_platform_files(desktop64_platform)
platform_headers = collections.defaultdict(set)
if generate_ios:
- build_target(simulator_platform, platform_headers)
+ #build_target(simulator_platform, platform_headers)
build_target(simulator64_platform, platform_headers)
build_target(device_platform, platform_headers)
build_target(device64_platform, platform_headers)
if generate_osx:
- build_target(desktop32_platform, platform_headers)
+ #build_target(desktop32_platform, platform_headers)
build_target(desktop64_platform, platform_headers)
mkdir_p('darwin_common/include')
--- libffi-3.2.1.old/configure 2014-11-12 12:59:57.000000000 +0100
+++ libffi-3.2.1/configure 2018-10-26 09:02:12.000000000 +0200
@@ -18725,11 +18725,11 @@
toolexecdir="${libdir}"/gcc-lib/'$(target_alias)'
toolexeclibdir="${libdir}"
fi
- multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
- case $multi_os_directory in
- .) ;; # Avoid trailing /.
- ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
- esac
+ # multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
+ # case $multi_os_directory in
+ # .) ;; # Avoid trailing /.
+ # ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ # esac
else
toolexeclibdir="${libdir}"
--- libffi-3.2.1.old/configure.ac 2014-11-12 12:56:51.000000000 +0100
+++ libffi-3.2.1/configure.ac 2018-10-26 09:00:50.000000000 +0200
@@ -601,11 +601,11 @@
toolexecdir="${libdir}"/gcc-lib/'$(target_alias)'
toolexeclibdir="${libdir}"
fi
- multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
- case $multi_os_directory in
- .) ;; # Avoid trailing /.
- ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
- esac
+ # multi_os_directory=`$CC $CFLAGS -print-multi-os-directory`
+ # case $multi_os_directory in
+ # .) ;; # Avoid trailing /.
+ # ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ # esac
AC_SUBST(toolexecdir)
else
toolexeclibdir="${libdir}"
--- libffi-3.2.1.old/libffi.xcodeproj/project.pbxproj 2018-10-26 17:31:30.000000000 +0200
+++ libffi-3.2.1/libffi.xcodeproj/project.pbxproj 2018-10-26 17:30:17.000000000 +0200
@@ -24,20 +24,11 @@
DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; };
DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; };
DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */; };
- DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */; };
- DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7174187F1D9B00A76262 /* darwin_i386.S */; };
- DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; };
- DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; };
- DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; settings = {ATTRIBUTES = (Private, ); }; };
DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Private, ); }; };
- DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7184187F1DA100A76262 /* fficonfig_i386.h */; settings = {ATTRIBUTES = (Private, ); }; };
DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; settings = {ATTRIBUTES = (Private, ); }; };
- DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Private, ); }; };
DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Private, ); }; };
DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */; };
- DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* darwin_i386.S */; };
DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; };
- DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -81,20 +72,11 @@
DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = "<group>"; };
DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = "<group>"; };
DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline_armv7.S; sourceTree = "<group>"; };
- DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = "<group>"; };
- DBFA7174187F1D9B00A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = "<group>"; };
- DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
- DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
- DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = "<group>"; };
DBFA7183187F1DA100A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = "<group>"; };
- DBFA7184187F1DA100A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = "<group>"; };
DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = "<group>"; };
- DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = "<group>"; };
DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = "<group>"; };
DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = "<group>"; };
- DBFA718B187F1DA100A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = "<group>"; };
DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = "<group>"; };
- DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
@@ -182,7 +164,6 @@
children = (
DBFA716B187F1D9B00A76262 /* aarch64 */,
DBFA716E187F1D9B00A76262 /* arm */,
- DBFA7172187F1D9B00A76262 /* x86 */,
);
path = src;
sourceTree = "<group>";
@@ -206,17 +187,6 @@
path = arm;
sourceTree = "<group>";
};
- DBFA7172187F1D9B00A76262 /* x86 */ = {
- isa = PBXGroup;
- children = (
- DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */,
- DBFA7174187F1D9B00A76262 /* darwin_i386.S */,
- DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */,
- DBFA7176187F1D9B00A76262 /* ffi_i386.c */,
- );
- path = x86;
- sourceTree = "<group>";
- };
DBFA7180187F1DA100A76262 /* darwin_osx */ = {
isa = PBXGroup;
children = (
@@ -229,11 +199,8 @@
DBFA7181187F1DA100A76262 /* include */ = {
isa = PBXGroup;
children = (
- DBFA7182187F1DA100A76262 /* ffi_i386.h */,
DBFA7183187F1DA100A76262 /* ffi_x86_64.h */,
- DBFA7184187F1DA100A76262 /* fficonfig_i386.h */,
DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */,
- DBFA7186187F1DA100A76262 /* ffitarget_i386.h */,
DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */,
);
path = include;
@@ -251,9 +218,7 @@
isa = PBXGroup;
children = (
DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */,
- DBFA718B187F1DA100A76262 /* darwin_i386.S */,
DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */,
- DBFA718D187F1DA100A76262 /* ffi_i386.c */,
);
path = x86;
sourceTree = "<group>";
@@ -269,12 +234,9 @@
DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */,
DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */,
DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */,
- DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */,
- DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */,
DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */,
DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */,
DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */,
- DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -321,7 +283,7 @@
DB13B15C1849DEB70010F42D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0510;
+ LastUpgradeCheck = 1000;
};
buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */;
compatibilityVersion = "Xcode 3.2";
@@ -366,7 +328,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx";
+ shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -375,17 +337,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */,
DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */,
DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */,
DBFA714E187F1D8600A76262 /* closures.c in Sources */,
DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */,
- DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */,
DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */,
- DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */,
DBFA7158187F1D8600A76262 /* raw_api.c in Sources */,
DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */,
- DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */,
DBFA715A187F1D8600A76262 /* types.c in Sources */,
DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */,
);
@@ -396,9 +354,7 @@
buildActionMask = 2147483647;
files = (
DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */,
- DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */,
DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */,
- DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */,
DBFA715B187F1D8600A76262 /* types.c in Sources */,
DBFA7159187F1D8600A76262 /* raw_api.c in Sources */,
DBFA714F187F1D8600A76262 /* closures.c in Sources */,
@@ -412,21 +368,74 @@
DB13B1601849DEB70010F42D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
darwin_common/include,
);
ONLY_ACTIVE_ARCH = YES;
+ VALID_ARCHS = x86_64;
};
name = Debug;
};
DB13B1611849DEB70010F42D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
darwin_common/include,
);
+ VALID_ARCHS = x86_64;
};
name = Release;
};
@@ -434,7 +443,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -467,7 +475,7 @@
"$(inherited)",
darwin_ios/include,
);
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
"IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ffi;
@@ -480,7 +488,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -507,7 +514,7 @@
"$(inherited)",
darwin_ios/include,
);
- IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
"IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = ffi;
--- libffi-3.2.1.old/libffi.xcodeproj/project.pbxproj.orig 2018-10-26 17:31:30.000000000 +0200
+++ libffi-3.2.1/libffi.xcodeproj/project.pbxproj.orig 2018-10-26 17:27:16.000000000 +0200
@@ -54,7 +54,7 @@
/* Begin PBXFileReference section */
DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
- DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ DB13B1911849DF510010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; };
DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = "<group>"; };
DBFA713F187F1D8600A76262 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = "<group>"; };
DBFA7140187F1D8600A76262 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = "<group>"; };
@@ -112,7 +112,7 @@
isa = PBXGroup;
children = (
DB13B1661849DF1E0010F42D /* libffi.a */,
- DB13B1911849DF510010F42D /* ffi.dylib */,
+ DB13B1911849DF510010F42D /* libffi.a */,
);
name = Products;
sourceTree = "<group>";
@@ -312,7 +312,7 @@
);
name = "libffi-Mac";
productName = ffi;
- productReference = DB13B1911849DF510010F42D /* ffi.dylib */;
+ productReference = DB13B1911849DF510010F42D /* libffi.a */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
@@ -535,6 +535,7 @@
COPY_PHASE_STRIP = NO;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
+ EXECUTABLE_EXTENSION = a;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
@@ -558,7 +559,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.6;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
- PRODUCT_NAME = ffi;
+ PRODUCT_NAME = libffi;
SDKROOT = macosx;
};
name = Debug;
@@ -583,6 +584,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
ENABLE_NS_ASSERTIONS = NO;
+ EXECUTABLE_EXTENSION = a;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -598,7 +600,7 @@
MACH_O_TYPE = staticlib;
MACOSX_DEPLOYMENT_TARGET = 10.6;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
- PRODUCT_NAME = ffi;
+ PRODUCT_NAME = libffi;
SDKROOT = macosx;
};
name = Release;

26
recipes/hostpython.py Normal file
View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
import sys
from toolchain import Recipe
class HostpythonAliasRecipe(Recipe):
is_alias = True
def init_after_import(self, ctx):
hostpython = ctx.state.get("hostpython")
if not hostpython:
# search in wanted_recipes if it's the first time
if "hostpython2" in ctx.wanted_recipes:
hostpython = "hostpython2"
elif "hostpython3" in ctx.wanted_recipes:
hostpython = "hostpython3"
else:
print("")
print("ERROR: No hostpython version set in the build.")
print("ERROR: Add python2 or python3 in your recipes:")
print("ERROR: ./toolchain.py build python3 ...")
print("")
sys.exit(1)
if hostpython:
self.depends = [hostpython]
recipe = HostpythonAliasRecipe()

View file

@ -5,7 +5,7 @@ import sh
import shutil import shutil
class HostpythonRecipe(Recipe): class Hostpython2Recipe(Recipe):
version = "2.7.1" version = "2.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2" url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
depends = ["hostlibffi"] depends = ["hostlibffi"]
@ -13,7 +13,9 @@ class HostpythonRecipe(Recipe):
archs = ["x86_64"] archs = ["x86_64"]
def init_with_ctx(self, ctx): def init_with_ctx(self, ctx):
super(HostpythonRecipe, self).init_with_ctx(ctx) super(Hostpython2Recipe, self).init_with_ctx(ctx)
self.set_hostpython(self, 2.7)
self.ctx.so_suffix = ".so"
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython", "bin", "python") self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython", "bin", "python")
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython", "bin", "pgen") self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython", "bin", "pgen")
print("Global: hostpython located at {}".format(self.ctx.hostpython)) print("Global: hostpython located at {}".format(self.ctx.hostpython))
@ -66,6 +68,7 @@ class HostpythonRecipe(Recipe):
]) ])
if "openssl.build_all" in self.ctx.state: if "openssl.build_all" in self.ctx.state:
build_env["LDFLAGS"] += " -L{}".format(join(self.ctx.dist_dir, "lib"))
build_env["CFLAGS"] += " -I{}".format(join(self.ctx.dist_dir, "include", build_env["CFLAGS"] += " -I{}".format(join(self.ctx.dist_dir, "include",
"x86_64", "openssl")) "x86_64", "openssl"))
@ -109,4 +112,4 @@ class HostpythonRecipe(Recipe):
join(self.ctx.dist_dir, "hostpython", "bin", "pgen")) join(self.ctx.dist_dir, "hostpython", "bin", "pgen"))
recipe = HostpythonRecipe() recipe = Hostpython2Recipe()

View file

@ -0,0 +1 @@
zlib zlibmodule.c -I$(prefix)/include -lz

View file

@ -0,0 +1,121 @@
from toolchain import Recipe, shprint, ensure_dir
from os.path import join, exists
import os
import sh
import shutil
class Hostpython3Recipe(Recipe):
version = "3.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tgz"
depends = []
optional_depends = ["openssl"]
archs = ["x86_64"]
def init_with_ctx(self, ctx):
super(Hostpython3Recipe, self).init_with_ctx(ctx)
self.set_hostpython(self, 3.7)
self.ctx.so_suffix = ".cpython-37m-darwin.so"
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython3", "bin", "python")
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython3", "bin", "pgen")
print("Global: hostpython located at {}".format(self.ctx.hostpython))
print("Global: hostpgen located at {}".format(self.ctx.hostpgen))
def prebuild_arch(self, arch):
if self.has_marker("patched"):
return
self.copy_file("ModulesSetup", "Modules/Setup.local")
# self.apply_patch("ssize-t-max.patch")
# self.apply_patch("dynload.patch")
# self.apply_patch("static-_sqlite3.patch")
# shutil.copy("Modules/Setup.dist", "Modules/Setup")
# if "openssl.build_all" in self.ctx.state:
# self.append_file("ModulesSetup.openssl", "Modules/Setup.local")
self.set_marker("patched")
def postbuild_arch(self, arch):
return
"""
makefile_fn = join(self.build_dir, "Makefile")
with open(makefile_fn) as fd:
lines = fd.readlines()
for index, line in enumerate(lines):
if "-bundle" not in line:
continue
parts = line.split(" ")
parts.remove("-bundle")
if "-bundle_loader" in parts:
i = parts.index("-bundle_loader")
parts.pop(i)
parts.pop(i)
lines[index] = " ".join(parts)
with open(makefile_fn, "w") as fd:
fd.writelines(lines)
"""
def get_build_env(self):
sdk_path = sh.xcrun("--sdk", "macosx", "--show-sdk-path").strip()
build_env = self.ctx.env.copy()
self.build_env_x86_84 = build_env
ccache = (build_env["CCACHE"] + ' ') if 'CCACHE' in build_env else ''
build_env["CC"] = ccache + "clang -Qunused-arguments -fcolor-diagnostics"
build_env["LDFLAGS"] = " ".join([
"-lsqlite3",
"-lffi",
"-L{}".format(join(self.ctx.dist_dir, "hostlibffi", "usr", "local", "lib"))
])
build_env["CFLAGS"] = " ".join([
"--sysroot={}".format(sdk_path),
"-arch x86_64",
"-mmacosx-version-min=10.12",
"-I{}".format(join(self.ctx.dist_dir, "hostlibffi", "usr", "local", "include"))
])
if "openssl.build_all" in self.ctx.state:
build_env["LDFLAGS"] += " -L{}".format(join(self.ctx.dist_dir, "lib"))
build_env["CFLAGS"] += " -I{}".format(join(self.ctx.dist_dir, "include",
"x86_64", "openssl"))
return build_env
def build_x86_64(self):
build_env = self.get_build_env()
configure = sh.Command(join(self.build_dir, "configure"))
shprint(configure,
"--prefix={}".format(join(self.ctx.dist_dir, "hostpython3")),
# "--disable-toolbox-glue",
# "--without-gcc",
_env=build_env)
shprint(sh.make, "-C", self.build_dir, self.ctx.concurrent_make,
_env=build_env)
# shutil.move("python", "hostpython")
# shutil.move("Parser/pgen", "Parser/hostpgen")
def install(self):
arch = list(self.filtered_archs)[0]
build_env = self.get_build_env()
build_dir = self.get_build_dir(arch.arch)
build_env["PATH"] = os.environ["PATH"]
# Compiling sometimes looks for Python-ast.py in the 'Python' i.s.o.
# the 'hostpython' folder. Create a symlink to fix. See issue #201
# shprint(sh.ln, "-s",
# join(build_dir, "hostpython3"),
# join(build_dir, "Python"))
shprint(sh.make, self.ctx.concurrent_make,
"-C", build_dir,
"install",
_env=build_env)
# pylib_dir = join(self.ctx.dist_dir, "hostpython3", "lib", "python3.7")
# if exists(pylib_dir):
# shutil.rmtree(pylib_dir)
# shutil.copytree(
# join(build_dir, "Lib"),
# pylib_dir)
# ensure_dir(join(pylib_dir, "config"))
# shutil.copy(
# join(build_dir, "Makefile"),
# join(pylib_dir, "config", "Makefile"))
shutil.copy(
join(self.ctx.dist_dir, "hostpython3", "bin", "python3"),
join(self.ctx.dist_dir, "hostpython3", "bin", "python"))
recipe = Hostpython3Recipe()

View file

@ -9,9 +9,8 @@ class IosRecipe(CythonRecipe):
pbx_frameworks = ["MessageUI", "CoreMotion", "UIKit"] pbx_frameworks = ["MessageUI", "CoreMotion", "UIKit"]
def install(self): def install(self):
self.install_python_package(name="ios.so", is_dir=False) self.install_python_package(
name=self.so_filename("ios"), is_dir=False)
recipe = IosRecipe() recipe = IosRecipe()

View file

@ -29,7 +29,7 @@ cdef void _send_email_done(char *status, void *data):
class IOSWebView(object): class IOSWebView(object):
def open(self, url, width, height): def open(self, url, width, height):
open_url_wbv(url, width, height) open_url_wbv(url, width, height)
def open_url_wbv(url, width, height): def open_url_wbv(url, width, height):
''' '''
@ -66,8 +66,12 @@ class IosBrowser(object):
open_url(url) open_url(url)
import webbrowser import webbrowser
webbrowser.register('ios', IosBrowser, None, -1) try:
# python 2
webbrowser.register('ios', IosBrowser, None, -1)
except:
# python 3
webbrowser.register('ios', IosBrowser, None, preferred=True)
# #
# API # API
# #
@ -119,7 +123,7 @@ def send_email(subject, text, mimetype=None, filename=None, filename_alias=None,
Example for sending a simple hello world:: Example for sending a simple hello world::
ios.send_email('This is my subject', ios.send_email('This is my subject',
'Hello you!\n\nThis is an hello world.') 'Hello you!\n\nThis is an hello world.')
Send a mail with an attachment:: Send a mail with an attachment::
@ -222,7 +226,7 @@ class IOSKeyboard(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(IOSKeyboard, self).__init__() super(IOSKeyboard, self).__init__()
NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, selector("keyboardWillShow"), "UIKeyboardWillShowNotification", None) NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, selector("keyboardWillShow"), "UIKeyboardWillShowNotification", None)
NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, selector("keyboardDidHide"), "UIKeyboardDidHideNotification", None) NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, selector("keyboardDidHide"), "UIKeyboardDidHideNotification", None)
@protocol('KeyboardDelegates') @protocol('KeyboardDelegates')
def keyboardWillShow(self, notification): def keyboardWillShow(self, notification):

View file

@ -0,0 +1,105 @@
"""
Author: Lawrence Du
E-mail: larrydu88@gmail.com
"""
from toolchain import CythonRecipe, shprint
import sh
from os.path import join
from os import environ, chdir
class KiventCoreRecipe(CythonRecipe):
version = 'master'
url = 'https://github.com/kivy/kivent/archive/{version}.zip'
name = 'kivent_core'
depends = ['libffi','kivy'] #note: unsure if libffi is necessary here
pre_build_ext=False
subbuilddir = False
cythonize = True
pbx_frameworks = ["OpenGLES"] #note: This line may be unnecessary
def get_recipe_env(self, arch):
env = super(KiventCoreRecipe,self).get_recipe_env(arch)
env['CYTHONPATH'] = self.get_recipe(
'kivy', self.ctx).get_build_dir(arch.arch)
return env
def get_build_dir(self,arch, sub=False):
"""
Call this to get the correct build_dir, where setup.py is located which is
actually under modules/core/setup.py
"""
builddir = super(KiventCoreRecipe, self).get_build_dir(str(arch))
if sub or self.subbuilddir:
core_build_dir = join (builddir, 'modules', 'core')
print "Core build directory is located at {}".format(core_build_dir)
return core_build_dir
else:
print "Building in {}".format(builddir)
return builddir
def build_arch(self, arch):
"""
Override build.arch to avoid calling setup.py here (Call it in
install() instead).
"""
self.subbuildir = True
self.cythonize_build()
self.biglink()
self.subbuilddir=False
def install(self):
"""
This method simply builds the command line call for calling
kivent_core/modules/core/setup.py
This constructs the equivalent of the command
"$python2.7 setup.py build_ext install"
only with the environment variables altered for each different architecture
The appropriate version of kivy also needs to be added to the path, and this
differs for each architecture (i386, x86_64, armv7, etc)
Note: This method is called by build_all() in toolchain.py
"""
arch = list(self.filtered_archs)[0]
build_dir = self.get_build_dir(arch.arch,sub=True)
print "Building kivent_core {} in {}".format(arch.arch,build_dir)
chdir(build_dir)
hostpython = sh.Command(self.ctx.hostpython)
#Get the appropriate environment for this recipe (including CYTHONPATH)
#build_env = arch.get_env()
build_env = self.get_recipe_env(arch)
dest_dir = join (self.ctx.dist_dir, "root", "python")
build_env['PYTHONPATH'] = join(dest_dir, 'lib', 'python2.7', 'site-packages')
#Add Architecture specific kivy path for 'import kivy' to PYTHONPATH
arch_kivy_path = self.get_recipe('kivy', self.ctx).get_build_dir(arch.arch)
build_env['PYTHONPATH'] = join( build_env['PYTHONPATH'],':',arch_kivy_path)
#Make sure you call kivent_core/modules/core/setup.py
subdir_path = self.get_build_dir(str(arch),sub=True)
setup_path = join(subdir_path,"setup.py")
#Print out directories for sanity check
print "ENVS", build_env
print "ROOT",self.ctx.root_dir
print "BUILD",self.ctx.build_dir
print "INCLUDE", self.ctx.include_dir
print "DISTDIR", self.ctx.dist_dir
print "ARCH KIVY LOC",self.get_recipe('kivy', self.ctx).get_build_dir(arch.arch)
shprint(hostpython, setup_path, "build_ext", "install", _env=build_env)
recipe = KiventCoreRecipe()

View file

@ -3,11 +3,11 @@ from os.path import join
class KivyRecipe(CythonRecipe): class KivyRecipe(CythonRecipe):
version = "1.10.0" version = "1.10.1"
url = "https://github.com/kivy/kivy/archive/{version}.zip" url = "https://github.com/kivy/kivy/archive/{version}.zip"
library = "libkivy.a" library = "libkivy.a"
depends = ["python", "sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios", depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
"pyobjus"] "pyobjus", "python"]
pbx_frameworks = ["OpenGLES", "Accelerate"] pbx_frameworks = ["OpenGLES", "Accelerate"]
pre_build_ext = True pre_build_ext = True
@ -40,4 +40,3 @@ class KivyRecipe(CythonRecipe):
recipe = KivyRecipe() recipe = KivyRecipe()

View file

@ -1,5 +1,6 @@
from toolchain import Recipe, shprint from toolchain import Recipe, shprint
import sh import sh
from os.path import exists
class LibffiRecipe(Recipe): class LibffiRecipe(Recipe):
@ -9,20 +10,29 @@ class LibffiRecipe(Recipe):
library = "build/Release-{arch.sdk}/libffi.a" library = "build/Release-{arch.sdk}/libffi.a"
include_per_arch = True include_per_arch = True
include_dir = "build_{arch.sdk}-{arch.arch}/include" include_dir = "build_{arch.sdk}-{arch.arch}/include"
include_name = "ffi"
archs = ["x86_64", "armv7", "arm64"]
def prebuild_arch(self, arch): def prebuild_arch(self, arch):
if self.has_marker("patched"): if self.has_marker("patched"):
return return
# necessary as it doesn't compile with XCode 6.0. If we use 5.1.1, the # XCode 10 minimum is 8.0 now.
# compiler for i386 is not working.
shprint(sh.sed, shprint(sh.sed,
"-i.bak", "-i.bak",
"s/-miphoneos-version-min=5.1.1/-miphoneos-version-min=6.0/g", "s/-miphoneos-version-min=5.1.1/-miphoneos-version-min=8.0/g",
"generate-darwin-source-and-headers.py") "generate-darwin-source-and-headers.py")
self.apply_patch("fix-win32-unreferenced-symbol.patch") self.apply_patch("fix-win32-unreferenced-symbol.patch")
self.set_marker("patched") self.set_marker("patched")
def build_arch(self, arch): def build_arch(self, arch):
if exists("generate-darwin-source-and-headers.py"):
shprint(
sh.mv,
"generate-darwin-source-and-headers.py",
"_generate-darwin-source-and-headers.py")
shprint(sh.touch, "generate-darwin-source-and-headers.py")
python27 = sh.Command("python2.7")
shprint(python27, "_generate-darwin-source-and-headers.py", "--only-ios")
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild,
"ONLY_ACTIVE_ARCH=NO", "ONLY_ACTIVE_ARCH=NO",
"ARCHS={}".format(arch.arch), "ARCHS={}".format(arch.arch),

View file

@ -1,15 +0,0 @@
from toolchain import Recipe
class MoodstocksRecipe(Recipe):
version = "4.1.5"
url = "https://moodstocks.com/static/releases/moodstocks-ios-sdk-{version}.zip"
frameworks = ["Moodstocks.framework"]
archs = ["i386"]
pbx_frameworks = [
"Moodstocks", "AVFoundation", "CoreMedia", "CoreVideo", "CFNetwork"]
recipe = MoodstocksRecipe()

View file

@ -1,17 +1,16 @@
from toolchain import Recipe, shprint from toolchain import Recipe, shprint
from os.path import join from os.path import join
import sh import sh
import os
class pkg_resources(Recipe): class pkg_resources(Recipe):
depends = ["hostpython", "python"] depends = ["hostpython", "python"]
archs = ['i386'] archs = ["x86_64"]
url = "" url = ""
def prebuild_arch(self, arch): def prebuild_arch(self, arch):
sh.cp("pkg_resources.py", join(self.ctx.dist_dir, "root", "python", "lib", "python2.7", "site-packages", "pkg_resources.py")) sh.cp("pkg_resources.py",
join(self.ctx.site_packages_dir, "pkg_resources.py"))
recipe = pkg_resources() recipe = pkg_resources()

View file

@ -1,12 +1,10 @@
# pure-python package, this can be removed when we'll support any python package
from toolchain import PythonRecipe from toolchain import PythonRecipe
class PlyerRecipe(PythonRecipe): class PlyerRecipe(PythonRecipe):
version = "master" version = "master"
url = "https://github.com/kivy/plyer/archive/{version}.zip" url = "https://github.com/kivy/plyer/archive/{version}.zip"
depends = ["python", "pyobjus"] depends = ["python", "pyobjus"]
archs = ["i386"] archs = ["x86_64"]
recipe = PlyerRecipe() recipe = PlyerRecipe()

13
recipes/pykka/__init__.py Normal file
View file

@ -0,0 +1,13 @@
from toolchain import PythonRecipe
class PykkaRecipe(PythonRecipe):
version = '1.2.1'
url = 'https://github.com/jodal/pykka/archive/v{version}.zip'
depends = ['python', 'host_setuptools']
site_packages_name = 'pykka'
recipe = PykkaRecipe()

View file

@ -1,14 +0,0 @@
from toolchain import PythonRecipe
class PyMoodstocksRecipe(PythonRecipe):
version = "master"
url = "https://github.com/tito/pymoodstocks/archive/{version}.zip"
depends = ["moodstocks", "kivy", "pyobjus"]
sources = ["src/ios"]
archs = ["i386"]
recipe = PyMoodstocksRecipe()

View file

@ -1,7 +1,4 @@
from toolchain import CythonRecipe, shprint from toolchain import CythonRecipe
from os.path import join
import sh
class PyobjusRecipe(CythonRecipe): class PyobjusRecipe(CythonRecipe):
version = "master" version = "master"
@ -10,23 +7,5 @@ class PyobjusRecipe(CythonRecipe):
depends = ["python"] depends = ["python"]
pre_build_ext = True pre_build_ext = True
def get_recipe_env(self, arch):
env = super(PyobjusRecipe, self).get_recipe_env(arch)
env["CC"] += " -I{}".format(
join(self.ctx.dist_dir, "include", arch.arch, "libffi"))
return env
def cythonize_build(self):
# don't use the cythonize, pyobjus don't support method rewriting
shprint(sh.find, self.build_dir, "-iname", "*.pyx",
"-exec", "cython", "{}", ";")
# ffi is installed somewhere else, this include doesn't work
# XXX ideally, we need to fix libffi installation...
shprint(sh.sed,
"-i.bak",
"s/ffi\///g",
"pyobjus/pyobjus.c")
recipe = PyobjusRecipe() recipe = PyobjusRecipe()

26
recipes/python.py Normal file
View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
import sys
from toolchain import Recipe
class PythonAliasRecipe(Recipe):
is_alias = True
def init_after_import(self, ctx):
python = ctx.state.get("python")
if not python:
# search in wanted_recipes if it's the first time
if "python2" in ctx.wanted_recipes:
python = "python2"
elif "python3" in ctx.wanted_recipes:
python = "python3"
else:
print("")
print("ERROR: No Python version set in the build.")
print("ERROR: Add python2 or python3 in your recipes:")
print("ERROR: ./toolchain.py build python3 ...")
print("")
sys.exit(1)
if python:
self.depends = [python]
recipe = PythonAliasRecipe()

View file

@ -4,21 +4,21 @@ import sh
import os import os
class PythonRecipe(Recipe): class Python2Recipe(Recipe):
version = "2.7.1" version = "2.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2" url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
depends = ["hostpython", "libffi", ] depends = ["hostpython2", "libffi"]
optional_depends = ["openssl"] optional_depends = ["openssl"]
library = "libpython2.7.a" library = "libpython2.7.a"
pbx_libraries = ["libz", "libbz2", "libsqlite3"] pbx_libraries = ["libz", "libbz2", "libsqlite3"]
def init_with_ctx(self, ctx): def init_with_ctx(self, ctx):
super(PythonRecipe, self).init_with_ctx(ctx) super(Python2Recipe, self).init_with_ctx(ctx)
self.ctx.python_ver_dir = "python2.7" self.set_python(self, 2.7)
self.ctx.python_prefix = join(ctx.dist_dir, "root", "python") ctx.python_ver_dir = "python2.7"
self.ctx.site_packages_dir = join( ctx.python_prefix = join(ctx.dist_dir, "root", "python")
ctx.dist_dir, "root", "python", "lib", ctx.python_ver_dir, ctx.site_packages_dir = join(
"site-packages") ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages")
def prebuild_arch(self, arch): def prebuild_arch(self, arch):
# common to all archs # common to all archs
@ -149,4 +149,4 @@ class PythonRecipe(Recipe):
os.chdir(oldpwd) os.chdir(oldpwd)
recipe = PythonRecipe() recipe = Python2Recipe()

View file

@ -0,0 +1,93 @@
#####################################################################
# Static compilation instructions for all binary modules.
#####################################################################
_asyncio _asynciomodule.c
_bisect _bisectmodule.c
_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c
# _bz2 _bz2module.c -I$(srcdir)/../bzip2/include -L$(srcdir)/../Support/BZip2 -lbz2
_codecs_cn cjkcodecs/_codecs_cn.c
_codecs_hk cjkcodecs/_codecs_hk.c
_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
_codecs_jp cjkcodecs/_codecs_jp.c
_codecs_kr cjkcodecs/_codecs_kr.c
_codecs_tw cjkcodecs/_codecs_tw.c
_contextvars _contextvarsmodule.c
_crypt _cryptmodule.c
_csv _csv.c
_datetime _datetimemodule.c
_elementtree _elementtree.c \
-I$(srcdir)/Modules/expat
-DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI
_hashlib _hashopenssl.c -lssl -DUSE_SSL
_heapq _heapqmodule.c
_json _json.c
_lsprof _lsprof.o rotatingtree.c
# _lzma _lzmamodule.c -I$(srcdir)/../xz/include -L$(srcdir)/../Support/XZ -llzma
_md5 md5module.c
_multibytecodec cjkcodecs/multibytecodec.c
# _multiprocessing _multiprocessing/multiprocessing.c _multiprocessing/semaphore.c
_opcode _opcode.c
_queue _queuemodule.c
_pickle _pickle.c
# _posixsubprocess _posixsubprocess.c
_random _randommodule.c
_sha1 sha1module.c
_sha3 _sha3/sha3module.c
_sha256 sha256module.c
_sha512 sha512module.c
_socket socketmodule.c
_sqlite3 -I$(srcdir)/Modules/_sqlite -DMODULE_NAME='\"sqlite3\"' -DSQLITE_OMIT_LOAD_EXTENSION -lsqlite3 \
_sqlite/cache.c \
_sqlite/connection.c \
_sqlite/cursor.c \
_sqlite/microprotocols.c \
_sqlite/module.c \
_sqlite/prepare_protocol.c \
_sqlite/row.c \
_sqlite/statement.c \
_sqlite/util.c
_ssl _ssl.c -lssl -DUSE_SSL
_struct _struct.c
array arraymodule.c
audioop audioop.c
binascii binascii.c
cmath cmathmodule.c _math.c
fcntl fcntlmodule.c
grp grpmodule.c
math mathmodule.c
# mmap mmapmodule.c
parser parsermodule.c
pyexpat expat/xmlparse.c \
expat/xmlrole.c \
expat/xmltok.c \
pyexpat.c \
-I$(srcdir)/Modules/expat \
-DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI -DXML_DEV_URANDOM
resource resource.c
select selectmodule.c
syslog syslogmodule.c
termios termios.c
unicodedata unicodedata.c
zlib zlibmodule.c -I$(prefix)/include -lz
#####################################################################
# Testing modules
#####################################################################
_ctypes_test _ctypes/_ctypes_test.c
_testbuffer _testbuffer.c
_testcapi _testcapimodule.c
_testimportmultiple _testimportmultiple.c
#####################################################################
# Modules that require additional frameworks
#####################################################################
#_curses _cursesmodule.c -lcurses -ltermcap
#_curses_panel _curses_panel.c -lpanel -lncurses
#_dbm _dbmmodule.c
#_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
#_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT -I... -L...
#nis nismodule.c -lnsl
#ossaudiodev
#readline readline.c -lreadline -ltermcap
#spwd spwdmodule.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

164
recipes/python3/__init__.py Normal file
View file

@ -0,0 +1,164 @@
from toolchain import Recipe, shprint
from os.path import join
import sh
import shutil
import os
class Python3Recipe(Recipe):
version = "3.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tgz"
depends = ["hostpython3", "libffi", "openssl"]
library = "libpython3.7m.a"
pbx_libraries = ["libz", "libbz2", "libsqlite3"]
def init_with_ctx(self, ctx):
super(Python3Recipe, self).init_with_ctx(ctx)
self.set_python(self, 3.7)
ctx.python_ver_dir = "python3.7"
ctx.python_prefix = join(ctx.dist_dir, "root", "python3")
ctx.site_packages_dir = join(
ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages")
def prebuild_arch(self, arch):
# common to all archs
if self.has_marker("patched"):
return
self.apply_patch("dynload.patch")
self.copy_file("ModulesSetup", "Modules/Setup.local")
self.append_file("ModulesSetup.mobile", "Modules/Setup.local")
self.apply_patch("xcompile.patch")
self.set_marker("patched")
def get_build_env(self, arch):
build_env = arch.get_env()
build_env["PATH"] = "{}:{}".format(
join(self.ctx.dist_dir, "hostpython3", "bin"),
os.environ["PATH"])
return build_env
def build_arch(self, arch):
build_env = self.get_build_env(arch)
configure = sh.Command(join(self.build_dir, "configure"))
py_arch = arch.arch
if py_arch == "armv7":
py_arch = "arm"
elif py_arch == "arm64":
py_arch = "aarch64"
prefix = join(self.ctx.dist_dir, "root", "python3")
shprint(configure,
"CC={}".format(build_env["CC"]),
"LD={}".format(build_env["LD"]),
"CFLAGS={}".format(build_env["CFLAGS"]),
"LDFLAGS={} -undefined dynamic_lookup".format(build_env["LDFLAGS"]),
# "--without-pymalloc",
"ac_cv_file__dev_ptmx=yes",
"ac_cv_file__dev_ptc=no",
"ac_cv_little_endian_double=yes",
"ac_cv_func_memrchr=no",
"ac_cv_func_getentropy=no",
"ac_cv_func_getresuid=no",
"ac_cv_func_getresgid=no",
"ac_cv_func_setresgid=no",
"ac_cv_func_setresuid=no",
"ac_cv_func_plock=no",
"ac_cv_func_dup3=no",
"ac_cv_func_pipe2=no",
"ac_cv_func_preadv=no",
"ac_cv_func_pwritev=no",
"ac_cv_func_preadv2=no",
"ac_cv_func_pwritev2=no",
"ac_cv_func_mkfifoat=no",
"ac_cv_func_mknodat=no",
"ac_cv_func_posix_fadvise=no",
"ac_cv_func_posix_fallocate=no",
"ac_cv_func_sigwaitinfo=no",
"ac_cv_func_sigtimedwait=no",
"ac_cv_func_clock_settime=no",
"ac_cv_func_pthread_getcpuclockid=no",
"ac_cv_func_sched_setscheduler=no",
"ac_cv_func_sched_setparam=no",
"ac_cv_func_clock_gettime=no",
"--host={}-apple-ios".format(py_arch),
"--build=x86_64-apple-darwin",
"--prefix={}".format(prefix),
"--without-ensurepip",
"--with-system-ffi",
# "--without-doc-strings",
"--enable-ipv6",
_env=build_env)
self.apply_patch("ctypes_duplicate.patch")
shprint(sh.make, self.ctx.concurrent_make)
def install(self):
arch = list(self.filtered_archs)[0]
build_env = self.get_build_env(arch)
build_dir = self.get_build_dir(arch.arch)
shprint(sh.make, self.ctx.concurrent_make,
"-C", build_dir,
"install",
"prefix={}".format(join(self.ctx.dist_dir, "root", "python3")),
_env=build_env)
# os.execve("/bin/bash", ["/bin/bash"], os.environ)
self.reduce_python()
def reduce_python(self):
print("Reduce python")
oldpwd = os.getcwd()
try:
print("Remove files unlikely to be used")
os.chdir(join(self.ctx.dist_dir, "root", "python3"))
# os.execve("/bin/bash", ["/bin/bash"], env=os.environ)
sh.rm("-rf", "bin", "share")
# platform binaries and configuration
os.chdir(join(
self.ctx.dist_dir, "root", "python3", "lib",
"python3.7", "config-3.7m-darwin"))
sh.rm("libpython3.7m.a")
sh.rm("python.o")
sh.rm("config.c.in")
sh.rm("makesetup")
sh.rm("install-sh")
# cleanup pkgconfig and compiled lib
os.chdir(join(self.ctx.dist_dir, "root", "python3", "lib"))
sh.rm("-rf", "pkgconfig")
sh.rm("-f", "libpython3.7m.a")
# cleanup python libraries
os.chdir(join(
self.ctx.dist_dir, "root", "python3", "lib", "python3.7"))
sh.rm("-rf", "wsgiref", "curses", "idlelib", "lib2to3",
"ensurepip", "turtledemo", "lib-dynload", "venv",
"pydoc_data")
sh.find(".", "-path", "*/test*/*", "-delete")
sh.find(".", "-name", "*.exe", "-type", "f", "-delete")
sh.find(".", "-name", "test*", "-type", "d", "-delete")
sh.find(".", "-iname", "*.pyc", "-delete")
sh.find(".", "-path", "*/__pycache__/*", "-delete")
sh.find(".", "-name", "__pycache__", "-type", "d", "-delete")
# now precompile to Python bytecode
hostpython = sh.Command(self.ctx.hostpython)
shprint(hostpython, "-m", "compileall", "-f", "-b")
# sh.find(".", "-iname", "*.py", "-delete")
# some pycache are recreated after compileall
sh.find(".", "-path", "*/__pycache__/*", "-delete")
sh.find(".", "-name", "__pycache__", "-type", "d", "-delete")
# create the lib zip
print("Create a python3.7.zip")
sh.mv("config-3.7m-darwin", "..")
sh.mv("site-packages", "..")
sh.zip("-r", "../python37.zip", sh.glob("*"))
sh.rm("-rf", sh.glob("*"))
sh.mv("../config-3.7m-darwin", ".")
sh.mv("../site-packages", ".")
finally:
os.chdir(oldpwd)
recipe = Python3Recipe()

View file

@ -0,0 +1,17 @@
--- Python-3.7.1/Modules/_ctypes/cfield.c-old 2018-11-03 13:47:40.000000000 +0100
+++ Python-3.7.1/Modules/_ctypes/cfield.c 2018-11-03 13:48:14.000000000 +0100
@@ -1633,6 +1633,7 @@
} ffi_type;
*/
+#if 0
/* align and size are bogus for void, but they must not be zero */
ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID };
@@ -1660,4 +1661,6 @@
ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER };
+#endif
+
/*---------------- EOF ----------------*/

View file

@ -0,0 +1,25 @@
--- Python-3.7.1/Python/dynload_shlib.c 2018-10-20 08:04:19.000000000 +0200
+++ Python-3.7.1/Python/dynload_shlib.c 2018-11-02 14:23:15.000000000 +0100
@@ -72,6 +72,16 @@
PyOS_snprintf(funcname, sizeof(funcname),
LEAD_UNDERSCORE "%.20s_%.200s", prefix, 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_SELF, funcname);
+
+#if 0
+
if (fp != NULL) {
int i;
struct _Py_stat_struct status;
@@ -126,4 +136,5 @@
handles[nhandles++].handle = handle;
p = (dl_funcptr) dlsym(handle, funcname);
return p;
+#endif
}

View file

@ -0,0 +1,145 @@
--- Python-3.7.1.orig/config.sub 2018-10-20 08:04:19.000000000 +0200
+++ Python-3.7.1/config.sub 2018-10-31 13:31:22.000000000 +0100
@@ -249,7 +249,7 @@
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][armk] \
| avr | avr32 \
| ba \
| be32 | be64 \
@@ -1524,7 +1524,11 @@
;;
-nacl*)
;;
- -ios)
+ -ios*)
+ ;;
+ -tvos*)
+ ;;
+ -watchos*)
;;
-none)
;;
--- Python-3.7.1.orig/configure 2018-10-20 08:04:19.000000000 +0200
+++ Python-3.7.1/configure 2018-10-31 13:41:38.000000000 +0100
@@ -3253,6 +3253,15 @@
*-*-cygwin*)
ac_sys_system=Cygwin
;;
+ *-apple-ios)
+ ac_sys_system=iOS
+ ;;
+ *-apple-tvos)
+ ac_sys_system=tvOS
+ ;;
+ *-apple-watchos)
+ ac_sys_system=watchOS
+ ;;
*)
# for now, limit cross builds to known configurations
MACHDEP="unknown"
@@ -3294,6 +3303,15 @@
_host_cpu=$host_cpu
esac
;;
+ *-apple-*)
+ case "$host_cpu" in
+ arm*)
+ _host_cpu=arm
+ ;;
+ *)
+ _host_cpu=$host_cpu
+ esac
+ ;;
*-*-cygwin*)
_host_cpu=
;;
@@ -3369,6 +3387,13 @@
define_xopen_source=no;;
Darwin/1[0-9].*)
define_xopen_source=no;;
+ # On iOS, defining _POSIX_C_SOURCE also disables platform specific features.
+ iOS/*)
+ define_xopen_source=no;;
+ tvOS/*)
+ define_xopen_source=no;;
+ watchOS/*)
+ define_xopen_source=no;;
# On AIX 4 and 5.1, mbstate_t is defined only when _XOPEN_SOURCE == 500 but
# used in wcsnrtombs() and mbsnrtowcs() even if _XOPEN_SOURCE is not defined
# or has another value. By not (re)defining it, the defaults come in place.
@@ -6176,11 +6201,17 @@
fi
if test "$cross_compiling" = yes; then
- case "$READELF" in
- readelf|:)
- as_fn_error $? "readelf for the host is required for cross builds" "$LINENO" 5
- ;;
- esac
+ case "$host" in
+ *-apple-*os)
+ # readelf not required for iOS cross builds.
+ ;;
+ *)
+ case "$READELF" in
+ readelf|:)
+ as_fn_error $? "readelf for the host is required for cross builds" "$LINENO" 5
+ ;;
+ esac
+ esac
fi
@@ -6803,8 +6834,6 @@
# tweak BASECFLAGS based on compiler and platform
case $GCC in
yes)
- CFLAGS_NODIST="$CFLAGS_NODIST -std=c99"
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wextra" >&5
$as_echo_n "checking for -Wextra... " >&6; }
ac_save_cc="$CC"
@@ -11281,6 +11310,10 @@
fi
;;
hp*|HP*) DYNLOADFILE="dynload_hpux.o";;
+ # Dynamic loading on iOS
+ iOS/*) DYNLOADFILE="dynload_shlib.o";;
+ tvOS/*) DYNLOADFILE="dynload_shlib.o";;
+ watchOS/*) DYNLOADFILE="dynload_shlib.o";;
*)
# use dynload_shlib.c and dlopen() if we have it; otherwise stub
# out any dynamic loading
@@ -18383,4 +18416,3 @@
echo "" >&6
echo "" >&6
fi
-
--- Python-3.7.1.orig/Modules/posixmodule.c 2018-10-20 08:04:19.000000000 +0200
+++ Python-3.7.1/Modules/posixmodule.c 2018-10-31 15:00:14.000000000 +0100
@@ -194,6 +194,22 @@
#endif /* _MSC_VER */
#endif /* ! __WATCOMC__ || __QNX__ */
+// iOS
+#undef HAVE_EXECV
+#undef HAVE_FORK
+#undef HAVE_FORK1
+#undef HAVE_FORKPTY
+#undef HAVE_GETGROUPS
+#undef HAVE_SCHED_H
+#undef HAVE_SENDFILE
+#undef HAVE_SETPRIORITY
+#undef HAVE_SPAWNV
+#undef HAVE_WAIT
+#undef HAVE_WAIT3
+#undef HAVE_WAIT4
+#undef HAVE_WAITPID
+#undef HAVE_SYSTEM
+#undef HAVE_FEXECVE
/*[clinic input]
# one of the few times we lie about this name!

View file

@ -3,14 +3,16 @@ import sh
class LibSDL2Recipe(Recipe): class LibSDL2Recipe(Recipe):
#version = "2.0.3" version = "2.0.8"
#url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz" url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz"
version = "iOS-improvements" #version = "iOS-improvements"
url = "https://bitbucket.org/slime73/sdl-experiments/get/{version}.tar.gz" #url = "https://bitbucket.org/slime73/sdl-experiments/get/{version}.tar.gz"
library = "Xcode-iOS/SDL/build/Release-{arch.sdk}/libSDL2.a" library = "Xcode-iOS/SDL/build/Release-{arch.sdk}/libSDL2.a"
include_dir = "include" include_dir = "include"
pbx_frameworks = ["OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics", pbx_frameworks = [
"CoreMotion"] "OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics",
"CoreMotion", "GameController", "AVFoundation", "Metal",
"UIKit"]
def prebuild_arch(self, arch): def prebuild_arch(self, arch):
if self.has_marker("patched"): if self.has_marker("patched"):
@ -26,9 +28,8 @@ class LibSDL2Recipe(Recipe):
"CC={}".format(env['CC']), "CC={}".format(env['CC']),
"-sdk", arch.sdk, "-sdk", arch.sdk,
"-project", "Xcode-iOS/SDL/SDL.xcodeproj", "-project", "Xcode-iOS/SDL/SDL.xcodeproj",
"-target", "libSDL", "-target", "libSDL-iOS",
"-configuration", "Release") "-configuration", "Release")
recipe = LibSDL2Recipe() recipe = LibSDL2Recipe()

1
requirements.txt Normal file
View file

@ -0,0 +1 @@
pbxproj==2.5.1

195
tests/test_python3/main.m Normal file
View file

@ -0,0 +1,195 @@
//
// main.m
// test_python3
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#include "/Users/tito/code/kivy-ios/dist/root/python3/include/python3.7m/Python.h"
#include "/Users/tito/code/kivy-ios/dist/include/common/sdl2/SDL_main.h"
#include <dlfcn.h>
void export_orientation();
void load_custom_builtin_importer();
int main(int argc, char *argv[]) {
int ret = 0;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// Change the executing path to YourApp
chdir("YourApp");
// Special environment to prefer .pyo, and don't write bytecode if .py are found
// because the process will not have a write attribute on the device.
// putenv("PYTHONOPTIMIZE=2");
putenv("PYTHONDONTWRITEBYTECODE=1");
putenv("PYTHONNOUSERSITE=1");
putenv("PYTHONPATH=.");
// putenv("PYTHONVERBOSE=1");
putenv("PYTHONUNBUFFERED=1");
// putenv("PYOBJUS_DEBUG=1");
// Kivy environment to prefer some implementation on iOS platform
putenv("KIVY_BUILD=ios");
putenv("KIVY_NO_CONFIG=1");
putenv("KIVY_NO_FILELOG=1");
putenv("KIVY_WINDOW=sdl2");
putenv("KIVY_IMAGE=imageio,tex");
putenv("KIVY_AUDIO=sdl2");
putenv("KIVY_GL_BACKEND=sdl2");
#ifndef DEBUG
putenv("KIVY_NO_CONSOLELOG=1");
#endif
// Export orientation preferences for Kivy
export_orientation();
NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
#if PY_MAJOR_VERSION == 2
NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]);
Py_SetPythonHome((char *)[resourcePath UTF8String]);
#else
NSString *python_home = [NSString stringWithFormat:@"PYTHONHOME=%@", resourcePath, nil];
putenv((char *)[python_home UTF8String]);
NSString *python_path = [NSString stringWithFormat:@"PYTHONPATH=%@:%@/lib/python3.7/:%@/lib/python3.7/site-packages", resourcePath, resourcePath, resourcePath, nil];
putenv((char *)[python_path UTF8String]);
NSString *tmp_path = [NSString stringWithFormat:@"TMP=%@/tmp", resourcePath, nil];
putenv((char *)[tmp_path UTF8String]);
#endif
NSLog(@"Initializing python");
Py_Initialize();
#if PY_MAJOR_VERSION == 2
PySys_SetArgv(argc, argv);
#else
wchar_t** python_argv = PyMem_RawMalloc(sizeof(wchar_t *) *argc);
for (int i = 0; i < argc; i++)
python_argv[i] = Py_DecodeLocale(argv[i], NULL);
PySys_SetArgv(argc, python_argv);
#endif
// If other modules are using the thread, we need to initialize them before.
PyEval_InitThreads();
// Add an importer for builtin modules
load_custom_builtin_importer();
// Search and start main.py
#if PY_MAJOR_VERSION == 2
#define MAIN_EXT @"pyo"
#else
#define MAIN_EXT @"py"
#endif
const char * prog = [
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:MAIN_EXT] cStringUsingEncoding:
NSUTF8StringEncoding];
NSLog(@"Running main.py: %s", prog);
FILE* fd = fopen(prog, "r");
if ( fd == NULL ) {
ret = 1;
NSLog(@"Unable to open main.py, abort.");
} else {
ret = PyRun_SimpleFileEx(fd, prog, 1);
if (ret != 0)
NSLog(@"Application quit abnormally!");
}
Py_Finalize();
NSLog(@"Leaving");
[pool release];
// Look like the app still runs even when we left here.
exit(ret);
return ret;
}
// This method reads the available orientations from the Info.plist file and
// shares them via an environment variable. Kivy will automatically set the
// orientation according to this environment value, if it exists. To restrict
// the allowed orientation, please see the comments inside.
void export_orientation() {
NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
NSArray *orientations = [info objectForKey:@"UISupportedInterfaceOrientations"];
// Orientation restrictions
// ========================
// Comment or uncomment blocks 1-3 in order the limit orientation support
// 1. Landscape only
// NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION=LandscapeLeft LandscapeRight"];
// 2. Portrait only
// NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION=Portrait PortraitUpsideDown"];
// 3. All orientations
NSString *result = [[NSString alloc] initWithString:@"KIVY_ORIENTATION="];
for (int i = 0; i < [orientations count]; i++) {
NSString *item = [orientations objectAtIndex:i];
item = [item substringFromIndex:22];
if (i > 0)
result = [result stringByAppendingString:@" "];
result = [result stringByAppendingString:item];
}
// ========================
putenv((char *)[result UTF8String]);
NSLog(@"Available orientation: %@", result);
}
void load_custom_builtin_importer() {
static const char *custom_builtin_importer = \
"import sys, imp, types\n" \
"from os import environ\n" \
"from os.path import exists, join\n" \
"try:\n" \
" # python 3\n"
" import _imp\n" \
" EXTS = _imp.extension_suffixes()\n" \
" sys.modules['subprocess'] = types.ModuleType(name='subprocess')\n" \
"except ImportError:\n" \
" EXTS = ['.so']\n"
"# Fake redirection to supress console output\n" \
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \
" class fakestd(object):\n" \
" def write(self, *args, **kw): pass\n" \
" def flush(self, *args, **kw): pass\n" \
" sys.stdout = fakestd()\n" \
" sys.stderr = fakestd()\n" \
"# Custom builtin importer for precompiled modules\n" \
"class CustomBuiltinImporter(object):\n" \
" def find_module(self, fullname, mpath=None):\n" \
" # print(f'find_module() fullname={fullname} mpath={mpath}')\n" \
" if '.' not in fullname:\n" \
" return\n" \
" if not mpath:\n" \
" return\n" \
" part = fullname.rsplit('.')[-1]\n" \
" for ext in EXTS:\n" \
" fn = join(list(mpath)[0], '{}{}'.format(part, ext))\n" \
" # print('find_module() {}'.format(fn))\n" \
" if exists(fn):\n" \
" return self\n" \
" return\n" \
" def load_module(self, fullname):\n" \
" f = fullname.replace('.', '_')\n" \
" mod = sys.modules.get(f)\n" \
" if mod is None:\n" \
" # print('LOAD DYNAMIC', f, sys.modules.keys())\n" \
" try:\n" \
" mod = imp.load_dynamic(f, f)\n" \
" except ImportError:\n" \
" import traceback; traceback.print_exc();\n" \
" # print('LOAD DYNAMIC FALLBACK', fullname)\n" \
" mod = imp.load_dynamic(fullname, fullname)\n" \
" sys.modules[fullname] = mod\n" \
" return mod\n" \
" return mod\n" \
"sys.meta_path.insert(0, CustomBuiltinImporter())";
PyRun_SimpleString(custom_builtin_importer);
}

View file

@ -0,0 +1,54 @@
print("Python 3 running!")
import sys
print(f"sys.path: {sys.path}")
import os
import traceback
modules_to_tests = [
"math", "_sre", "array",
"binascii", "multiprocessing",
"subprocess"
]
for name in modules_to_tests:
print(f"- import {name}: ", end="")
try:
__import__(name)
print("OK")
except ImportError:
print("FAIL")
traceback.print_exc()
# test pyobjus
print("- import pyobjus start")
import pyobjus
print("- import done")
from pyobjus import autoclass
NSNotificationCenter = autoclass("NSNotificationCenter")
# test ios
import ios
from kivy.app import App
from kivy.lang import Builder
class TestApp(App):
def build(self):
return Builder.load_string("""
RelativeLayout:
GridLayout:
cols: 2
Button:
text: "Hello Python 3!"
font_size: dp(48)
TextInput:
font_size: dp(24)
Widget
Widget
""")
TestApp().run()

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
""" """
Tool for compiling iOS toolchain Tool for compiling iOS toolchain
================================ ================================
@ -17,12 +17,19 @@ import io
import json import json
import shutil import shutil
import fnmatch import fnmatch
import tempfile
from datetime import datetime from datetime import datetime
try: try:
from urllib.request import FancyURLopener, urlcleanup from urllib.request import FancyURLopener, urlcleanup
except ImportError: except ImportError:
from urllib import FancyURLopener, urlcleanup from urllib import FancyURLopener, urlcleanup
try:
from pbxproj import XcodeProject
from pbxproj.pbxextensions.ProjectFiles import FileOptions
except ImportError:
print("ERROR: pbxproj requirements is missing")
print("To install: pip install -r requirements.txt")
sys.exit(0)
curdir = dirname(__file__) curdir = dirname(__file__)
sys.path.insert(0, join(curdir, "tools", "external")) sys.path.insert(0, join(curdir, "tools", "external"))
@ -37,7 +44,7 @@ def shprint(command, *args, **kwargs):
kwargs["_out_bufsize"] = 1 kwargs["_out_bufsize"] = 1
kwargs["_err_to_out"] = True kwargs["_err_to_out"] = True
for line in command(*args, **kwargs): for line in command(*args, **kwargs):
stdout.write(line) stdout.write(line.encode("ascii", "replace").decode())
def cache_execution(f): def cache_execution(f):
@ -103,7 +110,7 @@ class JsonStore(object):
return self.data.keys() return self.data.keys()
def remove_all(self, prefix): def remove_all(self, prefix):
for key in self.data.keys()[:]: for key in tuple(self.data.keys()):
if not key.startswith(prefix): if not key.startswith(prefix):
continue continue
del self.data[key] del self.data[key]
@ -142,35 +149,62 @@ class Arch(object):
self.ctx.include_dir, self.ctx.include_dir,
d.format(arch=self)) d.format(arch=self))
for d in self.ctx.include_dirs] for d in self.ctx.include_dirs]
include_dirs += ["-I{}".format(
join(self.ctx.dist_dir, "include", self.arch))]
env = {} env = {}
ccache = sh.which('ccache')
cc = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip() cc = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip()
cxx = sh.xcrun("-find", "-sdk", self.sdk, "clang++").strip()
# we put the flags in CC / CXX as sometimes the ./configure test
# with the preprocessor (aka CC -E) without CFLAGS, which fails for
# cross compiled projects
flags = " ".join([
"--sysroot", self.sysroot,
"-arch", self.arch,
"-pipe", "-no-cpp-precomp",
])
cc += " " + flags
cxx += " " + flags
use_ccache = environ.get("USE_CCACHE", "1")
ccache = None
if use_ccache == "1":
ccache = sh.which('ccache')
if ccache: if ccache:
ccache = ccache.strip() ccache = ccache.strip()
use_ccache = environ.get("USE_CCACHE", "1") env["USE_CCACHE"] = "1"
if use_ccache != '1': env["CCACHE"] = ccache
env["CC"] = cc env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
else: env.setdefault('CCACHE_MAXSIZE', '10G')
if not self._ccsh: env.setdefault('CCACHE_HARDLINK', 'true')
self._ccsh = ccsh = sh.mktemp().strip() env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,'
with open(ccsh, 'w') as f: 'include_file_mtime,include_file_ctime,file_stat_matches'))
f.write('#!/bin/sh\n')
f.write(ccache + ' ' + cc + ' "$@"\n')
sh.chmod('+x', ccsh)
else:
ccsh = self._ccsh
env["USE_CCACHE"] = '1'
env["CCACHE"] = ccache
env["CC"] = ccsh
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')}) if not self._ccsh:
env.setdefault('CCACHE_MAXSIZE', '10G') self._ccsh = tempfile.NamedTemporaryFile()
env.setdefault('CCACHE_HARDLINK', 'true') self._cxxsh = tempfile.NamedTemporaryFile()
env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,' sh.chmod("+x", self._ccsh.name)
'include_file_mtime,include_file_ctime,file_stat_matches')) sh.chmod("+x", self._cxxsh.name)
else: self._ccsh.write(b'#!/bin/sh\n')
env["CC"] = cc self._cxxsh.write(b'#!/bin/sh\n')
if ccache:
print("CC and CXX will use ccache")
self._ccsh.write(
(ccache + ' ' + cc + ' "$@"\n').encode("utf8"))
self._cxxsh.write(
(ccache + ' ' + cxx + ' "$@"\n').encode("utf8"))
else:
print("CC and CXX will not use ccache")
self._ccsh.write(
(cc + ' "$@"\n').encode("utf8"))
self._cxxsh.write(
(cxx + ' "$@"\n').encode("utf8"))
self._ccsh.flush()
self._cxxsh.flush()
env["CC"] = self._ccsh.name
env["CXX"] = self._cxxsh.name
env["AR"] = sh.xcrun("-find", "-sdk", self.sdk, "ar").strip() env["AR"] = sh.xcrun("-find", "-sdk", self.sdk, "ar").strip()
env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip() env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
env["OTHER_CFLAGS"] = " ".join(include_dirs) env["OTHER_CFLAGS"] = " ".join(include_dirs)
@ -178,11 +212,6 @@ class Arch(object):
"-L{}/{}".format(self.ctx.dist_dir, "lib"), "-L{}/{}".format(self.ctx.dist_dir, "lib"),
]) ])
env["CFLAGS"] = " ".join([ env["CFLAGS"] = " ".join([
"-arch", self.arch,
"-pipe", "-no-cpp-precomp",
"--sysroot", self.sysroot,
#"-I{}/common".format(self.ctx.include_dir),
#"-I{}/{}".format(self.ctx.include_dir, self.arch),
"-O3", "-O3",
self.version_min self.version_min
] + include_dirs) ] + include_dirs)
@ -284,6 +313,7 @@ class Context(object):
cython = None cython = None
sdkver = None sdkver = None
sdksimver = None sdksimver = None
so_suffix = None # set by one of the hostpython
def __init__(self): def __init__(self):
super(Context, self).__init__() super(Context, self).__init__()
@ -327,7 +357,7 @@ class Context(object):
self.install_dir = "{}/dist/root".format(self.root_dir) self.install_dir = "{}/dist/root".format(self.root_dir)
self.include_dir = "{}/dist/include".format(self.root_dir) self.include_dir = "{}/dist/include".format(self.root_dir)
self.archs = ( self.archs = (
ArchSimulator(self), # ArchSimulator(self),
Arch64Simulator(self), Arch64Simulator(self),
ArchIOS(self), ArchIOS(self),
Arch64IOS(self)) Arch64IOS(self))
@ -391,20 +421,31 @@ class Context(object):
return "IDEBuildOperationMaxNumberOfConcurrentCompileTasks={}".format(self.num_cores) return "IDEBuildOperationMaxNumberOfConcurrentCompileTasks={}".format(self.num_cores)
class Recipe(object): class Recipe(object):
version = None props = {
url = None "is_alias": False,
archs = [] "version": None,
depends = [] "url": None,
optional_depends = [] "archs": [],
library = None "depends": [],
libraries = [] "optional_depends": [],
include_dir = None "library": None,
include_per_arch = False "libraries": [],
frameworks = [] "include_dir": None,
sources = [] "include_per_arch": False,
pbx_frameworks = [] "include_name": None,
pbx_libraries = [] "frameworks": [],
"sources": [],
"pbx_frameworks": [],
"pbx_libraries": []
}
def __new__(cls):
for prop, value in cls.props.items():
if not hasattr(cls, prop):
setattr(cls, prop, value)
return super(Recipe, cls).__new__(cls)
# API available for recipes # API available for recipes
def download_file(self, url, filename, cwd=None): def download_file(self, url, filename, cwd=None):
@ -538,6 +579,12 @@ class Recipe(object):
""" """
return join(self.ctx.include_dir, "common", self.name) return join(self.ctx.include_dir, "common", self.name)
def so_filename(self, name):
"""Return the filename of a library with the appropriate so suffix
(.so for Python 2.7, .cpython-37m-darwin for Python 3.7)
"""
return "{}{}".format(name, self.ctx.so_suffix)
@property @property
def name(self): def name(self):
modname = self.__class__.__module__ modname = self.__class__.__module__
@ -582,10 +629,11 @@ class Recipe(object):
self.ctx = ctx self.ctx = ctx
include_dir = None include_dir = None
if self.include_dir: if self.include_dir:
include_name = self.include_name or self.name
if self.include_per_arch: if self.include_per_arch:
include_dir = join("{arch.arch}", self.name) include_dir = join("{arch.arch}", include_name)
else: else:
include_dir = join("common", self.name) include_dir = join("common", include_name)
if include_dir: if include_dir:
print("Include dir added: {}".format(include_dir)) print("Include dir added: {}".format(include_dir))
self.ctx.include_dirs.append(include_dir) self.ctx.include_dirs.append(include_dir)
@ -597,6 +645,37 @@ class Recipe(object):
arch = self.filtered_archs[0] arch = self.filtered_archs[0]
return arch.get_env() return arch.get_env()
def set_hostpython(self, instance, version):
state = self.ctx.state
hostpython = state.get("hostpython")
if hostpython is None:
state["hostpython"] = instance.name
state.sync()
elif hostpython != instance.name:
print("ERROR: Wanted to use {}".format(instance.name))
print("ERROR: but hostpython is already provided by {}.".format(
hostpython))
print("ERROR: You can have only one hostpython version compiled")
sys.exit(1)
self.ctx.python_major = int(version)
self.ctx.hostpython_ver = version
self.ctx.hostpython_recipe = instance
def set_python(self, instance, version):
state = self.ctx.state
python = state.get("python")
if python is None:
state["python"] = instance.name
state.sync()
elif python != instance.name:
print("ERROR: Wanted to use {}".format(instance.name))
print("ERROR: but python is already provided by {}.".format(
python))
print("ERROR: You can have only one python version compiled")
sys.exit(1)
self.ctx.python_ver = version
self.ctx.python_recipe = instance
@property @property
def archive_root(self): def archive_root(self):
key = "{}.archive_root".format(self.name) key = "{}.archive_root".format(self.name)
@ -627,6 +706,12 @@ class Recipe(object):
raise ValueError("Invalid path passed into {}".format(envname)) raise ValueError("Invalid path passed into {}".format(envname))
return d return d
def init_after_import(cls, ctx):
"""This can be used to dynamically set some variables
depending of the state
"""
pass
@cache_execution @cache_execution
def download(self): def download(self):
key = "{}.archive_root".format(self.name) key = "{}.archive_root".format(self.name)
@ -804,7 +889,8 @@ class Recipe(object):
arch_dir = "common" arch_dir = "common"
if self.include_per_arch: if self.include_per_arch:
arch_dir = arch.arch arch_dir = arch.arch
dest_dir = join(self.ctx.include_dir, arch_dir, self.name) include_name = self.include_name or self.name
dest_dir = join(self.ctx.include_dir, arch_dir, include_name)
if exists(dest_dir): if exists(dest_dir):
shutil.rmtree(dest_dir) shutil.rmtree(dest_dir)
build_dir = self.get_build_dir(arch.arch) build_dir = self.get_build_dir(arch.arch)
@ -832,7 +918,7 @@ class Recipe(object):
@classmethod @classmethod
def list_recipes(cls): def list_recipes(cls):
recipes_dir = join(dirname(__file__), "recipes") recipes_dir = join(dirname(__file__), "recipes")
for name in listdir(recipes_dir): for name in sorted(listdir(recipes_dir)):
fn = join(recipes_dir, name) fn = join(recipes_dir, name)
if isdir(fn): if isdir(fn):
yield name yield name
@ -853,6 +939,7 @@ class Recipe(object):
mod = importlib.import_module("recipes.{}".format(name)) mod = importlib.import_module("recipes.{}".format(name))
recipe = mod.recipe recipe = mod.recipe
recipe.recipe_dir = join(ctx.root_dir, "recipes", name) recipe.recipe_dir = join(ctx.root_dir, "recipes", name)
recipe.init_after_import(ctx)
if version: if version:
recipe.version = version recipe.version = version
@ -894,7 +981,7 @@ class PythonRecipe(Recipe):
"--prefix", iosbuild, "--prefix", iosbuild,
_env=env) _env=env)
dest_dir = join(self.ctx.site_packages_dir, name) dest_dir = join(self.ctx.site_packages_dir, name)
self.remove_junk(iosbuild) #self.remove_junk(iosbuild)
if is_dir: if is_dir:
if exists(dest_dir): if exists(dest_dir):
shutil.rmtree(dest_dir) shutil.rmtree(dest_dir)
@ -922,6 +1009,7 @@ class CythonRecipe(PythonRecipe):
filename = filename[len(self.build_dir) + 1:] filename = filename[len(self.build_dir) + 1:]
print("Cythonize {}".format(filename)) print("Cythonize {}".format(filename))
cmd = sh.Command(join(self.ctx.root_dir, "tools", "cythonize.py")) cmd = sh.Command(join(self.ctx.root_dir, "tools", "cythonize.py"))
hostpython = self.ctx.state.get("hostpython")
shprint(cmd, filename) shprint(cmd, filename)
def cythonize_build(self): def cythonize_build(self):
@ -968,6 +1056,7 @@ def build_recipes(names, ctx):
# gather all the dependencies # gather all the dependencies
print("Want to build {}".format(names)) print("Want to build {}".format(names))
graph = Graph() graph = Graph()
ctx.wanted_recipes = names[:]
recipe_to_load = names recipe_to_load = names
recipe_loaded = [] recipe_loaded = []
while names: while names:
@ -999,6 +1088,9 @@ def build_recipes(names, ctx):
build_order = list(graph.find_order()) build_order = list(graph.find_order())
print("Build order is {}".format(build_order)) print("Build order is {}".format(build_order))
recipes = [Recipe.get_recipe(name, ctx) for name in build_order] recipes = [Recipe.get_recipe(name, ctx) for name in build_order]
recipes = [recipe for recipe in recipes if not recipe.is_alias]
recipes_order = [recipe.name for recipe in recipes]
print("Recipe order is {}".format(recipes_order))
for recipe in recipes: for recipe in recipes:
recipe.init_with_ctx(ctx) recipe.init_with_ctx(ctx)
for recipe in recipes: for recipe in recipes:
@ -1010,6 +1102,15 @@ def ensure_dir(filename):
makedirs(filename) makedirs(filename)
def ensure_recipes_loaded(ctx):
for recipe in Recipe.list_recipes():
key = "{}.build_all".format(recipe)
if key not in ctx.state:
continue
recipe = Recipe.get_recipe(recipe, ctx)
recipe.init_with_ctx(ctx)
def update_pbxproj(filename): def update_pbxproj(filename):
# list all the compiled recipes # list all the compiled recipes
ctx = Context() ctx = Context()
@ -1046,39 +1147,42 @@ def update_pbxproj(filename):
print("-" * 70) print("-" * 70)
print("Analysis of {}".format(filename)) print("Analysis of {}".format(filename))
from mod_pbxproj import XcodeProject project = XcodeProject.load(filename)
project = XcodeProject.Load(filename)
sysroot = sh.xcrun("--sdk", "iphonesimulator", "--show-sdk-path").strip() sysroot = sh.xcrun("--sdk", "iphonesimulator", "--show-sdk-path").strip()
group = project.get_or_create_group("Frameworks") group = project.get_or_create_group("Frameworks")
g_classes = project.get_or_create_group("Classes") g_classes = project.get_or_create_group("Classes")
file_options = FileOptions(embed_framework=False, code_sign_on_copy=True)
for framework in pbx_frameworks: for framework in pbx_frameworks:
framework_name = "{}.framework".format(framework) framework_name = "{}.framework".format(framework)
if framework_name in frameworks: if framework_name in frameworks:
print("Ensure {} is in the project (local)".format(framework)) print("Ensure {} is in the project (pbx_frameworks, local)".format(framework))
f_path = join(ctx.dist_dir, "frameworks", framework_name) f_path = join(ctx.dist_dir, "frameworks", framework_name)
else: else:
print("Ensure {} is in the project (system)".format(framework)) print("Ensure {} is in the project (pbx_frameworks, system)".format(framework))
f_path = join(sysroot, "System", "Library", "Frameworks", f_path = join(sysroot, "System", "Library", "Frameworks",
"{}.framework".format(framework)) "{}.framework".format(framework))
project.add_file_if_doesnt_exist(f_path, parent=group, tree="DEVELOPER_DIR") project.add_file(f_path, parent=group, tree="DEVELOPER_DIR",
force=False, file_options=file_options)
for library in pbx_libraries: for library in pbx_libraries:
print("Ensure {} is in the project".format(library)) print("Ensure {} is in the project (pbx_libraries, dylib+tbd)".format(library))
f_path = join(sysroot, "usr", "lib", f_path = join(sysroot, "usr", "lib",
"{}.dylib".format(library)) "{}.dylib".format(library))
project.add_file_if_doesnt_exist(f_path, parent=group, tree="DEVELOPER_DIR") project.add_file(f_path, parent=group, tree="DEVELOPER_DIR", force=False)
f_path = join(sysroot, "usr", "lib",
"{}.tbd".format(library))
project.add_file(f_path, parent=group, tree="DEVELOPER_DIR", force=False)
for library in libraries: for library in libraries:
print("Ensure {} is in the project".format(library)) print("Ensure {} is in the project (libraries)".format(library))
project.add_file_if_doesnt_exist(library, parent=group) project.add_file(library, parent=group, force=False)
for name in sources: for name in sources:
print("Ensure {} sources are used".format(name)) print("Ensure {} sources are used".format(name))
fn = join(ctx.dist_dir, "sources", name) fn = join(ctx.dist_dir, "sources", name)
project.add_folder(fn, parent=g_classes) project.add_folder(fn, parent=g_classes)
if project.modified: project.backup()
project.backup() project.save()
project.save()
if __name__ == "__main__": if __name__ == "__main__":
@ -1167,9 +1271,12 @@ Xcode:
else: else:
ctx = Context() ctx = Context()
for name in Recipe.list_recipes(): for name in Recipe.list_recipes():
recipe = Recipe.get_recipe(name, ctx) try:
print("{recipe.name:<12} {recipe.version:<8}".format( recipe = Recipe.get_recipe(name, ctx)
recipe=recipe)) print("{recipe.name:<12} {recipe.version:<8}".format(recipe=recipe))
except:
pass
def clean(self): def clean(self):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -1226,6 +1333,14 @@ Xcode:
from cookiecutter.main import cookiecutter from cookiecutter.main import cookiecutter
ctx = Context() ctx = Context()
ensure_recipes_loaded(ctx)
if not hasattr(ctx, "python_ver"):
print("ERROR: No python recipes compiled!")
print("ERROR: You must have compiled at least python2 or")
print("ERROR: python3 recipes to be able to create a project.")
sys.exit(1)
template_dir = join(curdir, "tools", "templates") template_dir = join(curdir, "tools", "templates")
context = { context = {
"title": args.name, "title": args.name,
@ -1235,6 +1350,8 @@ Xcode:
"project_dir": realpath(args.directory), "project_dir": realpath(args.directory),
"version": "1.0.0", "version": "1.0.0",
"dist_dir": ctx.dist_dir, "dist_dir": ctx.dist_dir,
"python_version": ctx.python_ver,
"python_major": ctx.python_major
} }
cookiecutter(template_dir, no_input=True, extra_context=context) cookiecutter(template_dir, no_input=True, extra_context=context)
filename = join( filename = join(

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,11 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#include "{{ cookiecutter.kivy_dir }}/dist/root/python/include/python2.7/Python.h" {%- if cookiecutter.python_major == "2" %}
#include "{{ cookiecutter.kivy_dir }}/dist/root/python2/include/python2.7/Python.h"
{%- else %}
#include "{{ cookiecutter.kivy_dir }}/dist/root/python3/include/python3.7m/Python.h"
{%- endif %}
#include "{{ cookiecutter.kivy_dir }}/dist/include/common/sdl2/SDL_main.h" #include "{{ cookiecutter.kivy_dir }}/dist/include/common/sdl2/SDL_main.h"
#include <dlfcn.h> #include <dlfcn.h>
@ -22,11 +26,12 @@ int main(int argc, char *argv[]) {
// Special environment to prefer .pyo, and don't write bytecode if .py are found // Special environment to prefer .pyo, and don't write bytecode if .py are found
// because the process will not have a write attribute on the device. // because the process will not have a write attribute on the device.
putenv("PYTHONOPTIMIZE=2");
putenv("PYTHONDONTWRITEBYTECODE=1"); putenv("PYTHONDONTWRITEBYTECODE=1");
putenv("PYTHONNOUSERSITE=1"); putenv("PYTHONNOUSERSITE=1");
putenv("PYTHONPATH=."); putenv("PYTHONPATH=.");
//putenv("PYTHONVERBOSE=1"); putenv("PYTHONUNBUFFERED=1");
// putenv("PYTHONVERBOSE=1");
// putenv("PYOBJUS_DEBUG=1");
// Kivy environment to prefer some implementation on iOS platform // Kivy environment to prefer some implementation on iOS platform
putenv("KIVY_BUILD=ios"); putenv("KIVY_BUILD=ios");
@ -44,12 +49,31 @@ int main(int argc, char *argv[]) {
export_orientation(); export_orientation();
NSString * resourcePath = [[NSBundle mainBundle] resourcePath]; NSString * resourcePath = [[NSBundle mainBundle] resourcePath];
#if PY_MAJOR_VERSION == 2
NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]); NSLog(@"PythonHome is: %s", (char *)[resourcePath UTF8String]);
Py_SetPythonHome((char *)[resourcePath UTF8String]); Py_SetPythonHome((char *)[resourcePath UTF8String]);
#else
NSString *python_home = [NSString stringWithFormat:@"PYTHONHOME=%@", resourcePath, nil];
putenv((char *)[python_home UTF8String]);
NSString *python_path = [NSString stringWithFormat:@"PYTHONPATH=%@:%@/lib/python3.7/:%@/lib/python3.7/site-packages", resourcePath, resourcePath, resourcePath, nil];
putenv((char *)[python_path UTF8String]);
NSString *tmp_path = [NSString stringWithFormat:@"TMP=%@/tmp", resourcePath, nil];
putenv((char *)[tmp_path UTF8String]);
#endif
NSLog(@"Initializing python"); NSLog(@"Initializing python");
Py_Initialize(); Py_Initialize();
#if PY_MAJOR_VERSION == 2
PySys_SetArgv(argc, argv); PySys_SetArgv(argc, argv);
#else
wchar_t** python_argv = PyMem_RawMalloc(sizeof(wchar_t *) *argc);
for (int i = 0; i < argc; i++)
python_argv[i] = Py_DecodeLocale(argv[i], NULL);
PySys_SetArgv(argc, python_argv);
#endif
// If other modules are using the thread, we need to initialize them before. // If other modules are using the thread, we need to initialize them before.
PyEval_InitThreads(); PyEval_InitThreads();
@ -58,14 +82,20 @@ int main(int argc, char *argv[]) {
load_custom_builtin_importer(); load_custom_builtin_importer();
// Search and start main.py // Search and start main.py
#if PY_MAJOR_VERSION == 2
#define MAIN_EXT @"pyo"
#else
#define MAIN_EXT @"pyc"
#endif
const char * prog = [ const char * prog = [
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding: [[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:MAIN_EXT] cStringUsingEncoding:
NSUTF8StringEncoding]; NSUTF8StringEncoding];
NSLog(@"Running main.pyo: %s", prog); NSLog(@"Running main.py: %s", prog);
FILE* fd = fopen(prog, "r"); FILE* fd = fopen(prog, "r");
if ( fd == NULL ) { if ( fd == NULL ) {
ret = 1; ret = 1;
NSLog(@"Unable to open main.pyo, abort."); NSLog(@"Unable to open main.py, abort.");
} else { } else {
ret = PyRun_SimpleFileEx(fd, prog, 1); ret = PyRun_SimpleFileEx(fd, prog, 1);
if (ret != 0) if (ret != 0)
@ -117,9 +147,16 @@ void export_orientation() {
void load_custom_builtin_importer() { void load_custom_builtin_importer() {
static const char *custom_builtin_importer = \ static const char *custom_builtin_importer = \
"import sys, imp\n" \ "import sys, imp, types\n" \
"from os import environ\n" \ "from os import environ\n" \
"from os.path import exists, join\n" \ "from os.path import exists, join\n" \
"try:\n" \
" # python 3\n"
" import _imp\n" \
" EXTS = _imp.extension_suffixes()\n" \
" sys.modules['subprocess'] = types.ModuleType(name='subprocess')\n" \
"except ImportError:\n" \
" EXTS = ['.so']\n"
"# Fake redirection to supress console output\n" \ "# Fake redirection to supress console output\n" \
"if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \ "if environ.get('KIVY_NO_CONSOLE', '0') == '1':\n" \
" class fakestd(object):\n" \ " class fakestd(object):\n" \
@ -130,29 +167,32 @@ void load_custom_builtin_importer() {
"# Custom builtin importer for precompiled modules\n" \ "# Custom builtin importer for precompiled modules\n" \
"class CustomBuiltinImporter(object):\n" \ "class CustomBuiltinImporter(object):\n" \
" def find_module(self, fullname, mpath=None):\n" \ " def find_module(self, fullname, mpath=None):\n" \
" # print(f'find_module() fullname={fullname} mpath={mpath}')\n" \
" if '.' not in fullname:\n" \ " if '.' not in fullname:\n" \
" return\n" \ " return\n" \
" if not mpath:\n" \ " if not mpath:\n" \
" return\n" \ " return\n" \
" part = fullname.rsplit('.')[-1]\n" \ " part = fullname.rsplit('.')[-1]\n" \
" fn = join(mpath[0], '{}.so'.format(part))\n" \ " for ext in EXTS:\n" \
" if exists(fn):\n" \ " fn = join(list(mpath)[0], '{}{}'.format(part, ext))\n" \
" return self\n" \ " # print('find_module() {}'.format(fn))\n" \
" if exists(fn):\n" \
" return self\n" \
" return\n" \ " return\n" \
" def load_module(self, fullname):\n" \ " def load_module(self, fullname):\n" \
" f = fullname.replace('.', '_')\n" \ " f = fullname.replace('.', '_')\n" \
" mod = sys.modules.get(f)\n" \ " mod = sys.modules.get(f)\n" \
" if mod is None:\n" \ " if mod is None:\n" \
" # print 'LOAD DYNAMIC', f, sys.modules.keys()\n" \ " # print('LOAD DYNAMIC', f, sys.modules.keys())\n" \
" try:\n" \ " try:\n" \
" mod = imp.load_dynamic(f, f)\n" \ " mod = imp.load_dynamic(f, f)\n" \
" except ImportError:\n" \ " except ImportError:\n" \
" # import traceback; traceback.print_exc();\n" \ " import traceback; traceback.print_exc();\n" \
" # print 'LOAD DYNAMIC FALLBACK', fullname\n" \ " # print('LOAD DYNAMIC FALLBACK', fullname)\n" \
" mod = imp.load_dynamic(fullname, fullname)\n" \ " mod = imp.load_dynamic(fullname, fullname)\n" \
" sys.modules[fullname] = mod\n" \ " sys.modules[fullname] = mod\n" \
" return mod\n" \ " return mod\n" \
" return mod\n" \ " return mod\n" \
"sys.meta_path.append(CustomBuiltinImporter())"; "sys.meta_path.insert(0, CustomBuiltinImporter())";
PyRun_SimpleString(custom_builtin_importer); PyRun_SimpleString(custom_builtin_importer);
} }

View file

@ -11,7 +11,6 @@
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
2CB5F34717D5233A006187AB /* bridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB5F34617D5233A006187AB /* bridge.m */; }; 2CB5F34717D5233A006187AB /* bridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB5F34617D5233A006187AB /* bridge.m */; };
59738AB51A8BB5D8001B2C0C /* lib in Resources */ = {isa = PBXBuildFile; fileRef = 59738AB41A8BB5D8001B2C0C /* lib */; }; 59738AB51A8BB5D8001B2C0C /* lib in Resources */ = {isa = PBXBuildFile; fileRef = 59738AB41A8BB5D8001B2C0C /* lib */; };
59738AB71A8BB71F001B2C0C /* include in Resources */ = {isa = PBXBuildFile; fileRef = 59738AB61A8BB71F001B2C0C /* include */; };
59738ABB1A8E19AA001B2C0C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 59738ABA1A8E19AA001B2C0C /* Images.xcassets */; }; 59738ABB1A8E19AA001B2C0C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 59738ABA1A8E19AA001B2C0C /* Images.xcassets */; };
59738ADB1A8E62D6001B2C0C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */; }; 59738ADB1A8E62D6001B2C0C /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */; };
59738ADC1A8E62D6001B2C0C /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 59738AD11A8E62D6001B2C0C /* Default-667h@2x.png */; }; 59738ADC1A8E62D6001B2C0C /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 59738AD11A8E62D6001B2C0C /* Default-667h@2x.png */; };
@ -33,8 +32,7 @@
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
2CB5F34517D5233A006187AB /* bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = SOURCE_ROOT; }; 2CB5F34517D5233A006187AB /* bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = SOURCE_ROOT; };
2CB5F34617D5233A006187AB /* bridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bridge.m; sourceTree = SOURCE_ROOT; }; 2CB5F34617D5233A006187AB /* bridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bridge.m; sourceTree = SOURCE_ROOT; };
59738AB41A8BB5D8001B2C0C /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = lib; path = {{ cookiecutter.dist_dir }}/root/python/lib; sourceTree = "<group>"; }; 59738AB41A8BB5D8001B2C0C /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = lib; path = {{ cookiecutter.dist_dir }}/root/python{{ cookiecutter.python_major }}/lib; sourceTree = "<group>"; };
59738AB61A8BB71F001B2C0C /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; name = include; path = {{ cookiecutter.dist_dir }}/hostpython/include; sourceTree = "<group>"; };
59738ABA1A8E19AA001B2C0C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = {{ cookiecutter.project_name }}/Images.xcassets; sourceTree = "<group>"; }; 59738ABA1A8E19AA001B2C0C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = {{ cookiecutter.project_name }}/Images.xcassets; sourceTree = "<group>"; };
59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "LaunchImages/Default-568h@2x.png"; sourceTree = "<group>"; }; 59738AD01A8E62D6001B2C0C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "LaunchImages/Default-568h@2x.png"; sourceTree = "<group>"; };
59738AD11A8E62D6001B2C0C /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-667h@2x.png"; path = "LaunchImages/Default-667h@2x.png"; sourceTree = "<group>"; }; 59738AD11A8E62D6001B2C0C /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-667h@2x.png"; path = "LaunchImages/Default-667h@2x.png"; sourceTree = "<group>"; };
@ -104,7 +102,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
59738ABA1A8E19AA001B2C0C /* Images.xcassets */, 59738ABA1A8E19AA001B2C0C /* Images.xcassets */,
59738AB61A8BB71F001B2C0C /* include */,
59738AB41A8BB5D8001B2C0C /* lib */, 59738AB41A8BB5D8001B2C0C /* lib */,
01532DA9137C099F0076F6BF /* icon.png */, 01532DA9137C099F0076F6BF /* icon.png */,
8D1107310486CEB800E47090 /* {{ cookiecutter.project_name }}-Info.plist */, 8D1107310486CEB800E47090 /* {{ cookiecutter.project_name }}-Info.plist */,
@ -198,7 +195,6 @@
59738ADB1A8E62D6001B2C0C /* Default-568h@2x.png in Resources */, 59738ADB1A8E62D6001B2C0C /* Default-568h@2x.png in Resources */,
59738ADD1A8E62D6001B2C0C /* Default-763h@3x.png in Resources */, 59738ADD1A8E62D6001B2C0C /* Default-763h@3x.png in Resources */,
59738AE21A8E62D6001B2C0C /* Default-Portrait@3x~ipad.png in Resources */, 59738AE21A8E62D6001B2C0C /* Default-Portrait@3x~ipad.png in Resources */,
59738AB71A8BB71F001B2C0C /* include in Resources */,
59738AE51A8E62D6001B2C0C /* Default@3x.png in Resources */, 59738AE51A8E62D6001B2C0C /* Default@3x.png in Resources */,
59738ADF1A8E62D6001B2C0C /* Default-Landscape@2x.png in Resources */, 59738ADF1A8E62D6001B2C0C /* Default-Landscape@2x.png in Resources */,
); );
@ -234,7 +230,11 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash; shellPath = /bin/bash;
shellScript = "{{ cookiecutter.dist_dir }}/hostpython/bin/python -OO -m compileall \"$PROJECT_DIR\"/YourApp"; {%- if cookiecutter.python_major == "2" %}
shellScript = "{{ cookiecutter.dist_dir }}/hostpython2/bin/python -OO -m compileall \"$PROJECT_DIR\"/YourApp";
{%- else %}
shellScript = "{{ cookiecutter.dist_dir }}/hostpython3/bin/python -m compileall -f -b \"$PROJECT_DIR\"/YourApp";
{%- endif %}
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@ -250,7 +250,11 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash; shellPath = /bin/bash;
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -iname '*.py' -exec rm {} \\; -or -iname '*.pyc' -exec rm {} \\;"; {%- if cookiecutter.python_major == "2" %}
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -regex '.*\\.py[c]*' -delete";
{%- else %}
shellScript = "find \"$PROJECT_DIR\"/YourApp/ -regex '.*\\.py' -delete";
{%- endif %}
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@ -290,7 +294,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.1; IPHONEOS_DEPLOYMENT_TARGET = 8.1;
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"{{ cookiecutter.dist_dir }}/lib" "{{ cookiecutter.dist_dir }}/lib",
); );
ONLY_ACTIVE_ARCH = NO; ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = "-all_load"; OTHER_LDFLAGS = "-all_load";
@ -325,7 +329,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.1; IPHONEOS_DEPLOYMENT_TARGET = 8.1;
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\"$(PROJECT_DIR)/../build/lib\"" "\"$(PROJECT_DIR)/../build/lib\"",
); );
OTHER_LDFLAGS = "-all_load"; OTHER_LDFLAGS = "-all_load";
PRODUCT_NAME = {{ cookiecutter.project_name }}; PRODUCT_NAME = {{ cookiecutter.project_name }};
@ -343,6 +347,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
DEAD_CODE_STRIPPING = NO; DEAD_CODE_STRIPPING = NO;
ENABLE_BITCODE = NO;
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/; USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
}; };
name = Debug; name = Debug;
@ -351,6 +356,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
DEAD_CODE_STRIPPING = NO; DEAD_CODE_STRIPPING = NO;
ENABLE_BITCODE = NO;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/; USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
}; };