Merge branch 'master' of github.com:kivy/kivy-ios
This commit is contained in:
commit
654f71f481
5 changed files with 99 additions and 66 deletions
62
README.rst
62
README.rst
|
@ -12,6 +12,9 @@ The toolchain supports:
|
||||||
- iPhone Simulator (x86_64)
|
- iPhone Simulator (x86_64)
|
||||||
- iPhone / iOS (armv7 and arm64)
|
- iPhone / iOS (armv7 and arm64)
|
||||||
|
|
||||||
|
You can select between Python 2.7 or Python 3.7 by specifying the recipes
|
||||||
|
`python2` or `python3` when building.
|
||||||
|
|
||||||
These recipes are not ported to the new toolchain yet:
|
These recipes are not ported to the new toolchain yet:
|
||||||
|
|
||||||
- lxml
|
- lxml
|
||||||
|
@ -39,10 +42,10 @@ Currently, the toolchain requires a few tools for compilation. You will need:
|
||||||
brew install autoconf automake libtool pkg-config
|
brew install autoconf automake libtool pkg-config
|
||||||
brew link libtool
|
brew link libtool
|
||||||
|
|
||||||
#. Install Cython (0.26.1)::
|
#. Install Cython (0.28.1)::
|
||||||
|
|
||||||
# pip method if available (sudo might be needed.)
|
# pip method if available (sudo might be needed.)
|
||||||
pip install cython==0.26.1
|
pip install cython==0.28.1
|
||||||
|
|
||||||
|
|
||||||
Using the toolchain
|
Using the toolchain
|
||||||
|
@ -56,26 +59,50 @@ contained in a `recipe`.
|
||||||
You can list the available recipes and their versions with::
|
You can list the available recipes and their versions with::
|
||||||
|
|
||||||
$ ./toolchain.py recipes
|
$ ./toolchain.py recipes
|
||||||
|
audiostream master
|
||||||
|
click master
|
||||||
|
cymunk master
|
||||||
|
distribute 0.7.3
|
||||||
|
ffmpeg 2.6.3
|
||||||
|
ffpyplayer v3.2
|
||||||
|
flask master
|
||||||
freetype 2.5.5
|
freetype 2.5.5
|
||||||
hostpython 2.7.1
|
hostlibffi 3.2.1
|
||||||
|
hostpython2 2.7.1
|
||||||
|
hostpython3 3.7.1
|
||||||
ios master
|
ios master
|
||||||
kivy ios-poly-arch
|
itsdangerous master
|
||||||
|
jinja2 master
|
||||||
|
kivy 1.10.1
|
||||||
libffi 3.2.1
|
libffi 3.2.1
|
||||||
openssl 1.0.2e
|
libjpeg v9a
|
||||||
|
libpng 1.6.26
|
||||||
|
markupsafe master
|
||||||
|
moodstocks 4.1.5
|
||||||
|
numpy 1.9.1
|
||||||
|
openssl 1.0.2k
|
||||||
|
photolibrary master
|
||||||
|
pil 2.8.2
|
||||||
|
plyer master
|
||||||
|
pycrypto 2.6.1
|
||||||
|
pykka 1.2.1
|
||||||
pyobjus master
|
pyobjus master
|
||||||
python 2.7.1
|
python2 2.7.1
|
||||||
sdl2 iOS-improvements
|
python3 3.7.1
|
||||||
|
pyyaml 3.11
|
||||||
|
sdl2 2.0.8
|
||||||
sdl2_image 2.0.0
|
sdl2_image 2.0.0
|
||||||
sdl2_mixer 2.0.0
|
sdl2_mixer 2.0.0
|
||||||
sdl2_ttf 2.0.12
|
sdl2_ttf 2.0.12
|
||||||
|
werkzeug master
|
||||||
|
|
||||||
Then, start the compilation with::
|
Then, start the compilation with::
|
||||||
|
|
||||||
$ ./toolchain.py build kivy
|
$ ./toolchain.py build python3 kivy
|
||||||
|
|
||||||
You can build recipes at the same time by adding them as parameters::
|
You can build recipes at the same time by adding them as parameters::
|
||||||
|
|
||||||
$ ./toolchain.py build openssl kivy
|
$ ./toolchain.py build python3 openssl kivy
|
||||||
|
|
||||||
Recipe builds can be removed via the clean command e.g.::
|
Recipe builds can be removed via the clean command e.g.::
|
||||||
|
|
||||||
|
@ -87,7 +114,7 @@ You can think of it as follows: the kivy recipe will compile everything
|
||||||
necessary for a minimal working version of Kivy.
|
necessary for a minimal working version of Kivy.
|
||||||
|
|
||||||
Don't grab a coffee, just do diner. Compiling all the libraries for the first
|
Don't grab a coffee, just do diner. Compiling all the libraries for the first
|
||||||
time, 4x over (remember, 4 archs, 2 per platforms by default) will take time.
|
time, 3x over (remember, 3 archs, x86_64, armv7, arm64) will take time.
|
||||||
|
|
||||||
For a complete list of available commands, type::
|
For a complete list of available commands, type::
|
||||||
|
|
||||||
|
@ -155,7 +182,7 @@ Reducing the application size
|
||||||
If you would like to reduce the size of your distributed app, there are a few
|
If you would like to reduce the size of your distributed app, there are a few
|
||||||
things you can do to achieve this:
|
things you can do to achieve this:
|
||||||
|
|
||||||
#. Minimize the `build/python/lib/python27.zip`: this contains all the python
|
#. Minimize the `build/pythonX/lib/pythonXX.zip`: this contains all the python
|
||||||
modules. You can edit the zip file and remove all the files you'll not use
|
modules. You can edit the zip file and remove all the files you'll not use
|
||||||
(reduce encodings, remove xml, email...)
|
(reduce encodings, remove xml, email...)
|
||||||
|
|
||||||
|
@ -164,18 +191,18 @@ things you can do to achieve this:
|
||||||
Python dynamic modules and will remove needed symbols.
|
Python dynamic modules and will remove needed symbols.
|
||||||
|
|
||||||
#. By default, the iOS package compiles binaries for all processor
|
#. By default, the iOS package compiles binaries for all processor
|
||||||
architectures, namely x86, x86_64, armv7 and arm64 as per the guidelines from
|
architectures, namely x86_64, armv7 and arm64 as per the guidelines from
|
||||||
Apple. You can reduce the size of your ipa significantly by removing the
|
Apple. You can reduce the size of your ipa significantly by removing the
|
||||||
x86 and x86_64 architectures as they are usually used only for the emulator.
|
x86_64 architecture as they are used only for the emulator.
|
||||||
|
|
||||||
The procedure is to first compile/build all the host recipes as is::
|
The procedure is to first compile/build all the host recipes as is::
|
||||||
|
|
||||||
./toolchain.py build hostpython
|
./toolchain.py build hostpython3
|
||||||
|
|
||||||
Then build all the rest of the recipes using --arch=armv7 --arch=arm64
|
Then build all the rest of the recipes using --arch=armv7 --arch=arm64
|
||||||
arguments as follows::
|
arguments as follows::
|
||||||
|
|
||||||
./toolchain.py build kivy --arch=armv7 --arch=arm64
|
./toolchain.py build python3 kivy --arch=armv7 --arch=arm64
|
||||||
|
|
||||||
Note that these packages will not run in the iOS emulators, so use them
|
Note that these packages will not run in the iOS emulators, so use them
|
||||||
only for deployment.
|
only for deployment.
|
||||||
|
@ -213,6 +240,11 @@ Fatal error: "stdio.h" file not found
|
||||||
You must build with bitcode disabled (Xcode setting ENABLE_BITCODE should be No).
|
You must build with bitcode disabled (Xcode setting ENABLE_BITCODE should be No).
|
||||||
We don't support bitcode. You need to go to the project setting, and disable bitcode.
|
We don't support bitcode. You need to go to the project setting, and disable bitcode.
|
||||||
|
|
||||||
|
You don't have permissions to run
|
||||||
|
It is due to invalid archs, search for them and check it. Maybe you
|
||||||
|
targetted a simulator but have only armv7/arm64. Maybe you want to target
|
||||||
|
your iPad but it as only x86_64.
|
||||||
|
|
||||||
Support
|
Support
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
from toolchain import Recipe
|
from toolchain import Recipe
|
||||||
|
|
||||||
class HostpythonAliasRecipe(Recipe):
|
class HostpythonAliasRecipe(Recipe):
|
||||||
|
@ -13,9 +14,13 @@ class HostpythonAliasRecipe(Recipe):
|
||||||
elif "hostpython3" in ctx.wanted_recipes:
|
elif "hostpython3" in ctx.wanted_recipes:
|
||||||
hostpython = "hostpython3"
|
hostpython = "hostpython3"
|
||||||
else:
|
else:
|
||||||
print("WARNING: no hostpython set yet, so you need to specify")
|
print("")
|
||||||
print("WARNING: either hostpython2 or hostpython3 in your deps")
|
print("ERROR: No hostpython version set in the build.")
|
||||||
if python:
|
print("ERROR: Add python2 or python3 in your recipes:")
|
||||||
|
print("ERROR: ./toolchain.py build python3 ...")
|
||||||
|
print("")
|
||||||
|
sys.exit(1)
|
||||||
|
if hostpython:
|
||||||
self.depends = [hostpython]
|
self.depends = [hostpython]
|
||||||
|
|
||||||
recipe = HostpythonAliasRecipe()
|
recipe = HostpythonAliasRecipe()
|
||||||
|
|
|
@ -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,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import sys
|
||||||
from toolchain import Recipe
|
from toolchain import Recipe
|
||||||
|
|
||||||
class PythonAliasRecipe(Recipe):
|
class PythonAliasRecipe(Recipe):
|
||||||
|
@ -13,8 +14,12 @@ class PythonAliasRecipe(Recipe):
|
||||||
elif "python3" in ctx.wanted_recipes:
|
elif "python3" in ctx.wanted_recipes:
|
||||||
python = "python3"
|
python = "python3"
|
||||||
else:
|
else:
|
||||||
print("WARNING: no python set yet, so you need to specify")
|
print("")
|
||||||
print("WARNING: either python2 or python3 in your deps")
|
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:
|
if python:
|
||||||
self.depends = [python]
|
self.depends = [python]
|
||||||
|
|
||||||
|
|
57
toolchain.py
57
toolchain.py
|
@ -17,6 +17,7 @@ import io
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
import tempfile
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
try:
|
try:
|
||||||
from urllib.request import FancyURLopener, urlcleanup
|
from urllib.request import FancyURLopener, urlcleanup
|
||||||
|
@ -152,7 +153,6 @@ class Arch(object):
|
||||||
join(self.ctx.dist_dir, "include", self.arch))]
|
join(self.ctx.dist_dir, "include", self.arch))]
|
||||||
|
|
||||||
env = {}
|
env = {}
|
||||||
ccache = sh.which('ccache')
|
|
||||||
cc = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip()
|
cc = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip()
|
||||||
cxx = sh.xcrun("-find", "-sdk", self.sdk, "clang++").strip()
|
cxx = sh.xcrun("-find", "-sdk", self.sdk, "clang++").strip()
|
||||||
|
|
||||||
|
@ -166,40 +166,45 @@ class Arch(object):
|
||||||
])
|
])
|
||||||
cc += " " + flags
|
cc += " " + flags
|
||||||
cxx += " " + flags
|
cxx += " " + flags
|
||||||
|
|
||||||
|
use_ccache = environ.get("USE_CCACHE", "1")
|
||||||
|
ccache = None
|
||||||
|
if use_ccache == "1":
|
||||||
|
ccache = sh.which('ccache')
|
||||||
if ccache:
|
if ccache:
|
||||||
ccache = ccache.strip()
|
ccache = ccache.strip()
|
||||||
use_ccache = environ.get("USE_CCACHE", "1")
|
env["USE_CCACHE"] = "1"
|
||||||
if use_ccache != '1':
|
|
||||||
env["CC"] = cc
|
|
||||||
env["CXX"] = cxx
|
|
||||||
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)
|
|
||||||
self._cxxsh = cxxsh = sh.mktemp().strip()
|
|
||||||
with open(cxxsh, 'w') as f:
|
|
||||||
f.write('#!/bin/sh\n')
|
|
||||||
f.write(ccache + ' ' + cxx + ' "$@"\n')
|
|
||||||
sh.chmod('+x', cxxsh)
|
|
||||||
else:
|
|
||||||
ccsh = self._ccsh
|
|
||||||
cxxsh = self._cxxsh
|
|
||||||
env["USE_CCACHE"] = '1'
|
|
||||||
env["CCACHE"] = ccache
|
env["CCACHE"] = ccache
|
||||||
env["CC"] = ccsh
|
|
||||||
env["CXX"] = cxxsh
|
|
||||||
|
|
||||||
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
|
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
|
||||||
env.setdefault('CCACHE_MAXSIZE', '10G')
|
env.setdefault('CCACHE_MAXSIZE', '10G')
|
||||||
env.setdefault('CCACHE_HARDLINK', 'true')
|
env.setdefault('CCACHE_HARDLINK', 'true')
|
||||||
env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,'
|
env.setdefault('CCACHE_SLOPPINESS', ('file_macro,time_macros,'
|
||||||
'include_file_mtime,include_file_ctime,file_stat_matches'))
|
'include_file_mtime,include_file_ctime,file_stat_matches'))
|
||||||
|
|
||||||
|
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:
|
else:
|
||||||
env["CC"] = cc
|
print("CC and CXX will not use ccache")
|
||||||
env["CXX"] = cxx
|
self._ccsh.write(
|
||||||
|
(cc + ' "$@"\n').encode("utf8"))
|
||||||
|
self._cxxsh.write(
|
||||||
|
(cxx + ' "$@"\n').encode("utf8"))
|
||||||
|
self._ccsh.flush()
|
||||||
|
self._cxxsh.flush()
|
||||||
|
|
||||||
|
env["CC"] = self._ccsh.name
|
||||||
|
env["CXX"] = self._cxxsh.name
|
||||||
env["AR"] = sh.xcrun("-find", "-sdk", self.sdk, "ar").strip()
|
env["AR"] = sh.xcrun("-find", "-sdk", self.sdk, "ar").strip()
|
||||||
env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
|
env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
|
||||||
env["OTHER_CFLAGS"] = " ".join(include_dirs)
|
env["OTHER_CFLAGS"] = " ".join(include_dirs)
|
||||||
|
|
Loading…
Reference in a new issue