Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e93c1cffa3
57 changed files with 1825 additions and 1718 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ src/ios/iosbuild/
|
|||
src/ios/ios.c
|
||||
*.DS_Store*
|
||||
*-ios/
|
||||
__pycache__
|
||||
|
|
95
README.rst
95
README.rst
|
@ -4,15 +4,17 @@ Kivy for iOS
|
|||
This toolchain is designed to compile the necessary libraries for iOS to run
|
||||
your application and manage the creation of the Xcode project.
|
||||
|
||||
Currently, we do not provide any binary distributions of this toolchain, but we
|
||||
aim to. Until then, you do need to compile it at least once before creating
|
||||
your Xcode project.
|
||||
We do not provide any binary distributions of this toolchain.
|
||||
You do need to compile it at least once before creating your Xcode project.
|
||||
|
||||
The toolchain supports:
|
||||
|
||||
- iPhone Simulator (x86 and x86_64)
|
||||
- iPhone Simulator (x86_64)
|
||||
- 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:
|
||||
|
||||
- lxml
|
||||
|
@ -23,7 +25,15 @@ Requirements
|
|||
|
||||
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
|
||||
|
||||
|
@ -32,10 +42,10 @@ Currently, the toolchain requires a few tools for compilation. You will need:
|
|||
brew install autoconf automake libtool pkg-config
|
||||
brew link libtool
|
||||
|
||||
#. Install Cython (0.23)::
|
||||
#. Install Cython (0.28.1)::
|
||||
|
||||
# pip method if available (sudo might be needed.)
|
||||
pip install cython==0.23
|
||||
pip install cython==0.28.1
|
||||
|
||||
|
||||
Using the toolchain
|
||||
|
@ -49,26 +59,50 @@ contained in a `recipe`.
|
|||
You can list the available recipes and their versions with::
|
||||
|
||||
$ ./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
|
||||
hostpython 2.7.1
|
||||
hostlibffi 3.2.1
|
||||
hostpython2 2.7.1
|
||||
hostpython3 3.7.1
|
||||
ios master
|
||||
kivy ios-poly-arch
|
||||
itsdangerous master
|
||||
jinja2 master
|
||||
kivy 1.10.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
|
||||
python 2.7.1
|
||||
sdl2 iOS-improvements
|
||||
python2 2.7.1
|
||||
python3 3.7.1
|
||||
pyyaml 3.11
|
||||
sdl2 2.0.8
|
||||
sdl2_image 2.0.0
|
||||
sdl2_mixer 2.0.0
|
||||
sdl2_ttf 2.0.12
|
||||
werkzeug master
|
||||
|
||||
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::
|
||||
|
||||
$ ./toolchain.py build openssl kivy
|
||||
$ ./toolchain.py build python3 openssl kivy
|
||||
|
||||
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.
|
||||
|
||||
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::
|
||||
|
||||
|
@ -148,7 +182,7 @@ Reducing the application size
|
|||
If you would like to reduce the size of your distributed app, there are a few
|
||||
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
|
||||
(reduce encodings, remove xml, email...)
|
||||
|
||||
|
@ -157,18 +191,18 @@ things you can do to achieve this:
|
|||
Python dynamic modules and will remove needed symbols.
|
||||
|
||||
#. 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
|
||||
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::
|
||||
|
||||
./toolchain.py build hostpython
|
||||
./toolchain.py build hostpython3
|
||||
|
||||
Then build all the rest of the recipes using --arch=armv7 --arch=arm64
|
||||
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
|
||||
only for deployment.
|
||||
|
@ -202,10 +236,15 @@ FAQ
|
|||
|
||||
Fatal error: "stdio.h" file not found
|
||||
You need to install the Command line tools: `xcode-select --install`
|
||||
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
-------
|
||||
|
||||
|
@ -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
|
||||
* Email : kivy-users@googlegroups.com
|
||||
|
||||
We also have an IRC channel:
|
||||
We also have a Discord channel:
|
||||
|
||||
* Server : irc.freenode.net
|
||||
* Port : 6667, 6697 (SSL only)
|
||||
* Channel : #kivy
|
||||
* Server : https://chat.kivy.org
|
||||
* Channel : #support
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
@ -233,11 +271,10 @@ discussions about developing the Kivy framework and its sister projects:
|
|||
* Dev Group : https://groups.google.com/group/kivy-dev
|
||||
* Email : kivy-dev@googlegroups.com
|
||||
|
||||
IRC channel:
|
||||
Discord channel:
|
||||
|
||||
* Server : irc.freenode.net
|
||||
* Port : 6667, 6697 (SSL only)
|
||||
* Channel : #kivy-dev
|
||||
* Server : https://chat.kivy.org
|
||||
* Channel : #dev
|
||||
|
||||
License
|
||||
-------
|
||||
|
|
53
recipes/cymunk/__init__.py
Normal file
53
recipes/cymunk/__init__.py
Normal 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()
|
|
@ -1,5 +1,6 @@
|
|||
from toolchain import Recipe, shprint
|
||||
import sh
|
||||
from os.path import exists
|
||||
|
||||
|
||||
class LibffiRecipe(Recipe):
|
||||
|
@ -31,22 +32,30 @@ class LibffiRecipe(Recipe):
|
|||
self.apply_patch("public_include.patch")
|
||||
self.apply_patch("staticlib.patch")
|
||||
self.apply_patch("staticlib2.patch")
|
||||
self.apply_patch("libffi-xcode10.patch")
|
||||
self.set_marker("patched")
|
||||
|
||||
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",
|
||||
"ARCHS={}".format(arch.arch),
|
||||
"DSTROOT={}/hostlibffi".format(self.ctx.dist_dir),
|
||||
"-sdk", "macosx",
|
||||
"install", "installhdrs",
|
||||
"clean", "build", "installhdrs", "install",
|
||||
"-project", "libffi.xcodeproj",
|
||||
"-target", "libffi-Mac",
|
||||
"-configuration", "Release",
|
||||
"DSTROOT={}/hostlibffi".format(self.ctx.dist_dir))
|
||||
|
||||
"-scheme", "libffi-Mac",
|
||||
"-configuration", "Release")
|
||||
|
||||
def postbuild_arch(self, arch):
|
||||
pass
|
||||
|
||||
recipe = LibffiRecipe()
|
||||
|
||||
|
|
391
recipes/hostlibffi/libffi-xcode10.patch
Normal file
391
recipes/hostlibffi/libffi-xcode10.patch
Normal 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
26
recipes/hostpython.py
Normal 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()
|
|
@ -5,7 +5,7 @@ import sh
|
|||
import shutil
|
||||
|
||||
|
||||
class HostpythonRecipe(Recipe):
|
||||
class Hostpython2Recipe(Recipe):
|
||||
version = "2.7.1"
|
||||
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
||||
depends = ["hostlibffi"]
|
||||
|
@ -13,7 +13,9 @@ class HostpythonRecipe(Recipe):
|
|||
archs = ["x86_64"]
|
||||
|
||||
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.hostpgen = join(self.ctx.dist_dir, "hostpython", "bin", "pgen")
|
||||
print("Global: hostpython located at {}".format(self.ctx.hostpython))
|
||||
|
@ -66,6 +68,7 @@ class HostpythonRecipe(Recipe):
|
|||
])
|
||||
|
||||
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"))
|
||||
|
||||
|
@ -109,4 +112,4 @@ class HostpythonRecipe(Recipe):
|
|||
join(self.ctx.dist_dir, "hostpython", "bin", "pgen"))
|
||||
|
||||
|
||||
recipe = HostpythonRecipe()
|
||||
recipe = Hostpython2Recipe()
|
1
recipes/hostpython3/ModulesSetup
Normal file
1
recipes/hostpython3/ModulesSetup
Normal file
|
@ -0,0 +1 @@
|
|||
zlib zlibmodule.c -I$(prefix)/include -lz
|
121
recipes/hostpython3/__init__.py
Normal file
121
recipes/hostpython3/__init__.py
Normal 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()
|
|
@ -9,9 +9,8 @@ class IosRecipe(CythonRecipe):
|
|||
pbx_frameworks = ["MessageUI", "CoreMotion", "UIKit"]
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ cdef void _send_email_done(char *status, void *data):
|
|||
class IOSWebView(object):
|
||||
def open(self, url, width, height):
|
||||
open_url_wbv(url, width, height)
|
||||
|
||||
|
||||
|
||||
def open_url_wbv(url, width, height):
|
||||
'''
|
||||
|
@ -66,8 +66,12 @@ class IosBrowser(object):
|
|||
open_url(url)
|
||||
|
||||
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
|
||||
#
|
||||
|
@ -119,7 +123,7 @@ def send_email(subject, text, mimetype=None, filename=None, filename_alias=None,
|
|||
|
||||
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.')
|
||||
|
||||
Send a mail with an attachment::
|
||||
|
@ -222,7 +226,7 @@ class IOSKeyboard(object):
|
|||
def __init__(self, **kwargs):
|
||||
super(IOSKeyboard, self).__init__()
|
||||
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')
|
||||
def keyboardWillShow(self, notification):
|
||||
|
|
105
recipes/kivent_core/__init__.py
Normal file
105
recipes/kivent_core/__init__.py
Normal 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()
|
|
@ -3,11 +3,11 @@ from os.path import join
|
|||
|
||||
|
||||
class KivyRecipe(CythonRecipe):
|
||||
version = "1.10.0"
|
||||
version = "1.10.1"
|
||||
url = "https://github.com/kivy/kivy/archive/{version}.zip"
|
||||
library = "libkivy.a"
|
||||
depends = ["python", "sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
|
||||
"pyobjus"]
|
||||
depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
|
||||
"pyobjus", "python"]
|
||||
pbx_frameworks = ["OpenGLES", "Accelerate"]
|
||||
pre_build_ext = True
|
||||
|
||||
|
@ -40,4 +40,3 @@ class KivyRecipe(CythonRecipe):
|
|||
|
||||
|
||||
recipe = KivyRecipe()
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from toolchain import Recipe, shprint
|
||||
import sh
|
||||
from os.path import exists
|
||||
|
||||
|
||||
class LibffiRecipe(Recipe):
|
||||
|
@ -9,20 +10,29 @@ class LibffiRecipe(Recipe):
|
|||
library = "build/Release-{arch.sdk}/libffi.a"
|
||||
include_per_arch = True
|
||||
include_dir = "build_{arch.sdk}-{arch.arch}/include"
|
||||
include_name = "ffi"
|
||||
archs = ["x86_64", "armv7", "arm64"]
|
||||
|
||||
def prebuild_arch(self, arch):
|
||||
if self.has_marker("patched"):
|
||||
return
|
||||
# necessary as it doesn't compile with XCode 6.0. If we use 5.1.1, the
|
||||
# compiler for i386 is not working.
|
||||
# XCode 10 minimum is 8.0 now.
|
||||
shprint(sh.sed,
|
||||
"-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")
|
||||
self.apply_patch("fix-win32-unreferenced-symbol.patch")
|
||||
self.set_marker("patched")
|
||||
|
||||
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,
|
||||
"ONLY_ACTIVE_ARCH=NO",
|
||||
"ARCHS={}".format(arch.arch),
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
from toolchain import Recipe, shprint
|
||||
from os.path import join
|
||||
import sh
|
||||
import os
|
||||
|
||||
|
||||
class pkg_resources(Recipe):
|
||||
depends = ["hostpython", "python"]
|
||||
archs = ['i386']
|
||||
archs = ["x86_64"]
|
||||
url = ""
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
# pure-python package, this can be removed when we'll support any python package
|
||||
from toolchain import PythonRecipe
|
||||
|
||||
|
||||
class PlyerRecipe(PythonRecipe):
|
||||
version = "master"
|
||||
url = "https://github.com/kivy/plyer/archive/{version}.zip"
|
||||
depends = ["python", "pyobjus"]
|
||||
archs = ["i386"]
|
||||
archs = ["x86_64"]
|
||||
|
||||
|
||||
recipe = PlyerRecipe()
|
||||
|
||||
|
|
13
recipes/pykka/__init__.py
Normal file
13
recipes/pykka/__init__.py
Normal 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()
|
|
@ -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()
|
||||
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
from toolchain import CythonRecipe, shprint
|
||||
from os.path import join
|
||||
import sh
|
||||
|
||||
from toolchain import CythonRecipe
|
||||
|
||||
class PyobjusRecipe(CythonRecipe):
|
||||
version = "master"
|
||||
|
@ -10,23 +7,5 @@ class PyobjusRecipe(CythonRecipe):
|
|||
depends = ["python"]
|
||||
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()
|
||||
|
||||
|
||||
|
|
26
recipes/python.py
Normal file
26
recipes/python.py
Normal 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()
|
|
@ -4,21 +4,21 @@ import sh
|
|||
import os
|
||||
|
||||
|
||||
class PythonRecipe(Recipe):
|
||||
class Python2Recipe(Recipe):
|
||||
version = "2.7.1"
|
||||
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
||||
depends = ["hostpython", "libffi", ]
|
||||
depends = ["hostpython2", "libffi"]
|
||||
optional_depends = ["openssl"]
|
||||
library = "libpython2.7.a"
|
||||
pbx_libraries = ["libz", "libbz2", "libsqlite3"]
|
||||
|
||||
def init_with_ctx(self, ctx):
|
||||
super(PythonRecipe, self).init_with_ctx(ctx)
|
||||
self.ctx.python_ver_dir = "python2.7"
|
||||
self.ctx.python_prefix = join(ctx.dist_dir, "root", "python")
|
||||
self.ctx.site_packages_dir = join(
|
||||
ctx.dist_dir, "root", "python", "lib", ctx.python_ver_dir,
|
||||
"site-packages")
|
||||
super(Python2Recipe, self).init_with_ctx(ctx)
|
||||
self.set_python(self, 2.7)
|
||||
ctx.python_ver_dir = "python2.7"
|
||||
ctx.python_prefix = join(ctx.dist_dir, "root", "python")
|
||||
ctx.site_packages_dir = join(
|
||||
ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages")
|
||||
|
||||
def prebuild_arch(self, arch):
|
||||
# common to all archs
|
||||
|
@ -149,4 +149,4 @@ class PythonRecipe(Recipe):
|
|||
os.chdir(oldpwd)
|
||||
|
||||
|
||||
recipe = PythonRecipe()
|
||||
recipe = Python2Recipe()
|
93
recipes/python3/ModulesSetup
Normal file
93
recipes/python3/ModulesSetup
Normal 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
|
2
recipes/python3/ModulesSetup.mobile
Normal file
2
recipes/python3/ModulesSetup.mobile
Normal 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
164
recipes/python3/__init__.py
Normal 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()
|
17
recipes/python3/ctypes_duplicate.patch
Normal file
17
recipes/python3/ctypes_duplicate.patch
Normal 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 ----------------*/
|
25
recipes/python3/dynload.patch
Normal file
25
recipes/python3/dynload.patch
Normal 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
|
||||
}
|
145
recipes/python3/xcompile.patch
Normal file
145
recipes/python3/xcompile.patch
Normal 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!
|
|
@ -3,14 +3,16 @@ import sh
|
|||
|
||||
|
||||
class LibSDL2Recipe(Recipe):
|
||||
#version = "2.0.3"
|
||||
#url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz"
|
||||
version = "iOS-improvements"
|
||||
url = "https://bitbucket.org/slime73/sdl-experiments/get/{version}.tar.gz"
|
||||
version = "2.0.8"
|
||||
url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz"
|
||||
#version = "iOS-improvements"
|
||||
#url = "https://bitbucket.org/slime73/sdl-experiments/get/{version}.tar.gz"
|
||||
library = "Xcode-iOS/SDL/build/Release-{arch.sdk}/libSDL2.a"
|
||||
include_dir = "include"
|
||||
pbx_frameworks = ["OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics",
|
||||
"CoreMotion"]
|
||||
pbx_frameworks = [
|
||||
"OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics",
|
||||
"CoreMotion", "GameController", "AVFoundation", "Metal",
|
||||
"UIKit"]
|
||||
|
||||
def prebuild_arch(self, arch):
|
||||
if self.has_marker("patched"):
|
||||
|
@ -26,9 +28,8 @@ class LibSDL2Recipe(Recipe):
|
|||
"CC={}".format(env['CC']),
|
||||
"-sdk", arch.sdk,
|
||||
"-project", "Xcode-iOS/SDL/SDL.xcodeproj",
|
||||
"-target", "libSDL",
|
||||
"-target", "libSDL-iOS",
|
||||
"-configuration", "Release")
|
||||
|
||||
|
||||
recipe = LibSDL2Recipe()
|
||||
|
||||
|
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
pbxproj==2.5.1
|
195
tests/test_python3/main.m
Normal file
195
tests/test_python3/main.m
Normal 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);
|
||||
}
|
54
tests/test_python3/main.py
Normal file
54
tests/test_python3/main.py
Normal 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()
|
249
toolchain.py
249
toolchain.py
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tool for compiling iOS toolchain
|
||||
================================
|
||||
|
@ -17,12 +17,19 @@ import io
|
|||
import json
|
||||
import shutil
|
||||
import fnmatch
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
try:
|
||||
from urllib.request import FancyURLopener, urlcleanup
|
||||
except ImportError:
|
||||
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__)
|
||||
sys.path.insert(0, join(curdir, "tools", "external"))
|
||||
|
||||
|
@ -37,7 +44,7 @@ def shprint(command, *args, **kwargs):
|
|||
kwargs["_out_bufsize"] = 1
|
||||
kwargs["_err_to_out"] = True
|
||||
for line in command(*args, **kwargs):
|
||||
stdout.write(line)
|
||||
stdout.write(line.encode("ascii", "replace").decode())
|
||||
|
||||
|
||||
def cache_execution(f):
|
||||
|
@ -103,7 +110,7 @@ class JsonStore(object):
|
|||
return self.data.keys()
|
||||
|
||||
def remove_all(self, prefix):
|
||||
for key in self.data.keys()[:]:
|
||||
for key in tuple(self.data.keys()):
|
||||
if not key.startswith(prefix):
|
||||
continue
|
||||
del self.data[key]
|
||||
|
@ -142,35 +149,62 @@ class Arch(object):
|
|||
self.ctx.include_dir,
|
||||
d.format(arch=self))
|
||||
for d in self.ctx.include_dirs]
|
||||
include_dirs += ["-I{}".format(
|
||||
join(self.ctx.dist_dir, "include", self.arch))]
|
||||
|
||||
env = {}
|
||||
ccache = sh.which('ccache')
|
||||
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:
|
||||
ccache = ccache.strip()
|
||||
use_ccache = environ.get("USE_CCACHE", "1")
|
||||
if use_ccache != '1':
|
||||
env["CC"] = cc
|
||||
else:
|
||||
if not self._ccsh:
|
||||
self._ccsh = ccsh = sh.mktemp().strip()
|
||||
with open(ccsh, 'w') as f:
|
||||
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["USE_CCACHE"] = "1"
|
||||
env["CCACHE"] = ccache
|
||||
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
|
||||
env.setdefault('CCACHE_MAXSIZE', '10G')
|
||||
env.setdefault('CCACHE_HARDLINK', 'true')
|
||||
env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,'
|
||||
'include_file_mtime,include_file_ctime,file_stat_matches'))
|
||||
|
||||
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
|
||||
env.setdefault('CCACHE_MAXSIZE', '10G')
|
||||
env.setdefault('CCACHE_HARDLINK', 'true')
|
||||
env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,'
|
||||
'include_file_mtime,include_file_ctime,file_stat_matches'))
|
||||
else:
|
||||
env["CC"] = cc
|
||||
if not self._ccsh:
|
||||
self._ccsh = tempfile.NamedTemporaryFile()
|
||||
self._cxxsh = tempfile.NamedTemporaryFile()
|
||||
sh.chmod("+x", self._ccsh.name)
|
||||
sh.chmod("+x", self._cxxsh.name)
|
||||
self._ccsh.write(b'#!/bin/sh\n')
|
||||
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["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
|
||||
env["OTHER_CFLAGS"] = " ".join(include_dirs)
|
||||
|
@ -178,11 +212,6 @@ class Arch(object):
|
|||
"-L{}/{}".format(self.ctx.dist_dir, "lib"),
|
||||
])
|
||||
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",
|
||||
self.version_min
|
||||
] + include_dirs)
|
||||
|
@ -284,6 +313,7 @@ class Context(object):
|
|||
cython = None
|
||||
sdkver = None
|
||||
sdksimver = None
|
||||
so_suffix = None # set by one of the hostpython
|
||||
|
||||
def __init__(self):
|
||||
super(Context, self).__init__()
|
||||
|
@ -327,7 +357,7 @@ class Context(object):
|
|||
self.install_dir = "{}/dist/root".format(self.root_dir)
|
||||
self.include_dir = "{}/dist/include".format(self.root_dir)
|
||||
self.archs = (
|
||||
ArchSimulator(self),
|
||||
# ArchSimulator(self),
|
||||
Arch64Simulator(self),
|
||||
ArchIOS(self),
|
||||
Arch64IOS(self))
|
||||
|
@ -391,20 +421,31 @@ class Context(object):
|
|||
return "IDEBuildOperationMaxNumberOfConcurrentCompileTasks={}".format(self.num_cores)
|
||||
|
||||
|
||||
|
||||
class Recipe(object):
|
||||
version = None
|
||||
url = None
|
||||
archs = []
|
||||
depends = []
|
||||
optional_depends = []
|
||||
library = None
|
||||
libraries = []
|
||||
include_dir = None
|
||||
include_per_arch = False
|
||||
frameworks = []
|
||||
sources = []
|
||||
pbx_frameworks = []
|
||||
pbx_libraries = []
|
||||
props = {
|
||||
"is_alias": False,
|
||||
"version": None,
|
||||
"url": None,
|
||||
"archs": [],
|
||||
"depends": [],
|
||||
"optional_depends": [],
|
||||
"library": None,
|
||||
"libraries": [],
|
||||
"include_dir": None,
|
||||
"include_per_arch": False,
|
||||
"include_name": None,
|
||||
"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
|
||||
def download_file(self, url, filename, cwd=None):
|
||||
|
@ -538,6 +579,12 @@ class Recipe(object):
|
|||
"""
|
||||
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
|
||||
def name(self):
|
||||
modname = self.__class__.__module__
|
||||
|
@ -582,10 +629,11 @@ class Recipe(object):
|
|||
self.ctx = ctx
|
||||
include_dir = None
|
||||
if self.include_dir:
|
||||
include_name = self.include_name or self.name
|
||||
if self.include_per_arch:
|
||||
include_dir = join("{arch.arch}", self.name)
|
||||
include_dir = join("{arch.arch}", include_name)
|
||||
else:
|
||||
include_dir = join("common", self.name)
|
||||
include_dir = join("common", include_name)
|
||||
if include_dir:
|
||||
print("Include dir added: {}".format(include_dir))
|
||||
self.ctx.include_dirs.append(include_dir)
|
||||
|
@ -597,6 +645,37 @@ class Recipe(object):
|
|||
arch = self.filtered_archs[0]
|
||||
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
|
||||
def archive_root(self):
|
||||
key = "{}.archive_root".format(self.name)
|
||||
|
@ -627,6 +706,12 @@ class Recipe(object):
|
|||
raise ValueError("Invalid path passed into {}".format(envname))
|
||||
return d
|
||||
|
||||
def init_after_import(cls, ctx):
|
||||
"""This can be used to dynamically set some variables
|
||||
depending of the state
|
||||
"""
|
||||
pass
|
||||
|
||||
@cache_execution
|
||||
def download(self):
|
||||
key = "{}.archive_root".format(self.name)
|
||||
|
@ -804,7 +889,8 @@ class Recipe(object):
|
|||
arch_dir = "common"
|
||||
if self.include_per_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):
|
||||
shutil.rmtree(dest_dir)
|
||||
build_dir = self.get_build_dir(arch.arch)
|
||||
|
@ -832,7 +918,7 @@ class Recipe(object):
|
|||
@classmethod
|
||||
def list_recipes(cls):
|
||||
recipes_dir = join(dirname(__file__), "recipes")
|
||||
for name in listdir(recipes_dir):
|
||||
for name in sorted(listdir(recipes_dir)):
|
||||
fn = join(recipes_dir, name)
|
||||
if isdir(fn):
|
||||
yield name
|
||||
|
@ -853,6 +939,7 @@ class Recipe(object):
|
|||
mod = importlib.import_module("recipes.{}".format(name))
|
||||
recipe = mod.recipe
|
||||
recipe.recipe_dir = join(ctx.root_dir, "recipes", name)
|
||||
recipe.init_after_import(ctx)
|
||||
|
||||
if version:
|
||||
recipe.version = version
|
||||
|
@ -894,7 +981,7 @@ class PythonRecipe(Recipe):
|
|||
"--prefix", iosbuild,
|
||||
_env=env)
|
||||
dest_dir = join(self.ctx.site_packages_dir, name)
|
||||
self.remove_junk(iosbuild)
|
||||
#self.remove_junk(iosbuild)
|
||||
if is_dir:
|
||||
if exists(dest_dir):
|
||||
shutil.rmtree(dest_dir)
|
||||
|
@ -922,6 +1009,7 @@ class CythonRecipe(PythonRecipe):
|
|||
filename = filename[len(self.build_dir) + 1:]
|
||||
print("Cythonize {}".format(filename))
|
||||
cmd = sh.Command(join(self.ctx.root_dir, "tools", "cythonize.py"))
|
||||
hostpython = self.ctx.state.get("hostpython")
|
||||
shprint(cmd, filename)
|
||||
|
||||
def cythonize_build(self):
|
||||
|
@ -968,6 +1056,7 @@ def build_recipes(names, ctx):
|
|||
# gather all the dependencies
|
||||
print("Want to build {}".format(names))
|
||||
graph = Graph()
|
||||
ctx.wanted_recipes = names[:]
|
||||
recipe_to_load = names
|
||||
recipe_loaded = []
|
||||
while names:
|
||||
|
@ -999,6 +1088,9 @@ def build_recipes(names, ctx):
|
|||
build_order = list(graph.find_order())
|
||||
print("Build order is {}".format(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:
|
||||
recipe.init_with_ctx(ctx)
|
||||
for recipe in recipes:
|
||||
|
@ -1010,6 +1102,15 @@ def ensure_dir(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):
|
||||
# list all the compiled recipes
|
||||
ctx = Context()
|
||||
|
@ -1046,39 +1147,42 @@ def update_pbxproj(filename):
|
|||
print("-" * 70)
|
||||
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()
|
||||
|
||||
group = project.get_or_create_group("Frameworks")
|
||||
g_classes = project.get_or_create_group("Classes")
|
||||
file_options = FileOptions(embed_framework=False, code_sign_on_copy=True)
|
||||
for framework in pbx_frameworks:
|
||||
framework_name = "{}.framework".format(framework)
|
||||
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)
|
||||
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",
|
||||
"{}.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:
|
||||
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",
|
||||
"{}.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:
|
||||
print("Ensure {} is in the project".format(library))
|
||||
project.add_file_if_doesnt_exist(library, parent=group)
|
||||
print("Ensure {} is in the project (libraries)".format(library))
|
||||
project.add_file(library, parent=group, force=False)
|
||||
for name in sources:
|
||||
print("Ensure {} sources are used".format(name))
|
||||
fn = join(ctx.dist_dir, "sources", name)
|
||||
project.add_folder(fn, parent=g_classes)
|
||||
|
||||
|
||||
if project.modified:
|
||||
project.backup()
|
||||
project.save()
|
||||
project.backup()
|
||||
project.save()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1167,9 +1271,12 @@ Xcode:
|
|||
else:
|
||||
ctx = Context()
|
||||
for name in Recipe.list_recipes():
|
||||
recipe = Recipe.get_recipe(name, ctx)
|
||||
print("{recipe.name:<12} {recipe.version:<8}".format(
|
||||
recipe=recipe))
|
||||
try:
|
||||
recipe = Recipe.get_recipe(name, ctx)
|
||||
print("{recipe.name:<12} {recipe.version:<8}".format(recipe=recipe))
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
def clean(self):
|
||||
parser = argparse.ArgumentParser(
|
||||
|
@ -1226,6 +1333,14 @@ Xcode:
|
|||
|
||||
from cookiecutter.main import cookiecutter
|
||||
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")
|
||||
context = {
|
||||
"title": args.name,
|
||||
|
@ -1235,6 +1350,8 @@ Xcode:
|
|||
"project_dir": realpath(args.directory),
|
||||
"version": "1.0.0",
|
||||
"dist_dir": ctx.dist_dir,
|
||||
"python_version": ctx.python_ver,
|
||||
"python_major": ctx.python_major
|
||||
}
|
||||
cookiecutter(template_dir, no_input=True, extra_context=context)
|
||||
filename = join(
|
||||
|
|
1498
tools/external/mod_pbxproj.py
vendored
1498
tools/external/mod_pbxproj.py
vendored
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,11 @@
|
|||
|
||||
#import <Foundation/Foundation.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 <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
|
||||
// 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("PYTHONVERBOSE=1");
|
||||
// putenv("PYOBJUS_DEBUG=1");
|
||||
|
||||
// Kivy environment to prefer some implementation on iOS platform
|
||||
putenv("KIVY_BUILD=ios");
|
||||
|
@ -44,12 +49,31 @@ int main(int argc, char *argv[]) {
|
|||
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();
|
||||
|
@ -58,14 +82,20 @@ int main(int argc, char *argv[]) {
|
|||
load_custom_builtin_importer();
|
||||
|
||||
// Search and start main.py
|
||||
#if PY_MAJOR_VERSION == 2
|
||||
#define MAIN_EXT @"pyo"
|
||||
#else
|
||||
#define MAIN_EXT @"pyc"
|
||||
#endif
|
||||
|
||||
const char * prog = [
|
||||
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding:
|
||||
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:MAIN_EXT] cStringUsingEncoding:
|
||||
NSUTF8StringEncoding];
|
||||
NSLog(@"Running main.pyo: %s", prog);
|
||||
NSLog(@"Running main.py: %s", prog);
|
||||
FILE* fd = fopen(prog, "r");
|
||||
if ( fd == NULL ) {
|
||||
ret = 1;
|
||||
NSLog(@"Unable to open main.pyo, abort.");
|
||||
NSLog(@"Unable to open main.py, abort.");
|
||||
} else {
|
||||
ret = PyRun_SimpleFileEx(fd, prog, 1);
|
||||
if (ret != 0)
|
||||
|
@ -117,9 +147,16 @@ void export_orientation() {
|
|||
|
||||
void load_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.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" \
|
||||
|
@ -130,29 +167,32 @@ void load_custom_builtin_importer() {
|
|||
"# 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" \
|
||||
" fn = join(mpath[0], '{}.so'.format(part))\n" \
|
||||
" if exists(fn):\n" \
|
||||
" return self\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" \
|
||||
" # 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" \
|
||||
" 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.append(CustomBuiltinImporter())";
|
||||
"sys.meta_path.insert(0, CustomBuiltinImporter())";
|
||||
PyRun_SimpleString(custom_builtin_importer);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
|
||||
2CB5F34717D5233A006187AB /* bridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CB5F34617D5233A006187AB /* bridge.m */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
|
@ -33,8 +32,7 @@
|
|||
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; };
|
||||
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>"; };
|
||||
59738AB61A8BB71F001B2C0C /* include */ = {isa = PBXFileReference; lastKnownFileType = folder; name = include; path = {{ cookiecutter.dist_dir }}/hostpython/include; sourceTree = "<group>"; };
|
||||
59738AB41A8BB5D8001B2C0C /* lib */ = {isa = PBXFileReference; lastKnownFileType = folder; name = lib; path = {{ cookiecutter.dist_dir }}/root/python{{ cookiecutter.python_major }}/lib; 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>"; };
|
||||
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;
|
||||
children = (
|
||||
59738ABA1A8E19AA001B2C0C /* Images.xcassets */,
|
||||
59738AB61A8BB71F001B2C0C /* include */,
|
||||
59738AB41A8BB5D8001B2C0C /* lib */,
|
||||
01532DA9137C099F0076F6BF /* icon.png */,
|
||||
8D1107310486CEB800E47090 /* {{ cookiecutter.project_name }}-Info.plist */,
|
||||
|
@ -198,7 +195,6 @@
|
|||
59738ADB1A8E62D6001B2C0C /* Default-568h@2x.png in Resources */,
|
||||
59738ADD1A8E62D6001B2C0C /* Default-763h@3x.png in Resources */,
|
||||
59738AE21A8E62D6001B2C0C /* Default-Portrait@3x~ipad.png in Resources */,
|
||||
59738AB71A8BB71F001B2C0C /* include in Resources */,
|
||||
59738AE51A8E62D6001B2C0C /* Default@3x.png in Resources */,
|
||||
59738ADF1A8E62D6001B2C0C /* Default-Landscape@2x.png in Resources */,
|
||||
);
|
||||
|
@ -234,7 +230,11 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
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 */
|
||||
|
||||
|
@ -250,7 +250,11 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
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 */
|
||||
|
||||
|
@ -290,7 +294,7 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"{{ cookiecutter.dist_dir }}/lib"
|
||||
"{{ cookiecutter.dist_dir }}/lib",
|
||||
);
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
|
@ -325,7 +329,7 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(PROJECT_DIR)/../build/lib\""
|
||||
"\"$(PROJECT_DIR)/../build/lib\"",
|
||||
);
|
||||
OTHER_LDFLAGS = "-all_load";
|
||||
PRODUCT_NAME = {{ cookiecutter.project_name }};
|
||||
|
@ -343,6 +347,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
ENABLE_BITCODE = NO;
|
||||
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -351,6 +356,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
ENABLE_BITCODE = NO;
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
USER_HEADER_SEARCH_PATHS = {{ cookiecutter.dist_dir }}/root/include/;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue