From e93a7dd7c7a62755a5d09c3b0aa6a4ae1e041be8 Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Sat, 4 Mar 2023 23:48:41 +0100 Subject: [PATCH] Support ARM64 Simulator + Introduce build platform concept --- .ci/constants.py | 2 +- kivy_ios/recipes/click/__init__.py | 6 +- kivy_ios/recipes/ffmpeg/__init__.py | 8 +- kivy_ios/recipes/ffpyplayer/__init__.py | 10 +- kivy_ios/recipes/flask/__init__.py | 6 +- kivy_ios/recipes/freetype/__init__.py | 8 +- kivy_ios/recipes/hostopenssl/__init__.py | 12 +- kivy_ios/recipes/hostpython3/__init__.py | 16 +- kivy_ios/recipes/itsdangerous/__init__.py | 6 +- kivy_ios/recipes/jinja2/__init__.py | 6 +- kivy_ios/recipes/kivent_core/__init__.py | 28 +- kivy_ios/recipes/kivy/__init__.py | 8 +- kivy_ios/recipes/libcurl/__init__.py | 11 +- kivy_ios/recipes/libffi/__init__.py | 17 +- kivy_ios/recipes/libjpeg/__init__.py | 8 +- kivy_ios/recipes/libpng/__init__.py | 6 +- kivy_ios/recipes/libzbar/__init__.py | 18 +- kivy_ios/recipes/markupsafe/__init__.py | 6 +- kivy_ios/recipes/netifaces/__init__.py | 10 +- kivy_ios/recipes/numpy/__init__.py | 10 +- kivy_ios/recipes/openssl/__init__.py | 25 +- kivy_ios/recipes/pillow/__init__.py | 22 +- kivy_ios/recipes/plyer/__init__.py | 1 - kivy_ios/recipes/py3dns/__init__.py | 2 +- kivy_ios/recipes/pycrypto/__init__.py | 16 +- kivy_ios/recipes/python3/__init__.py | 22 +- kivy_ios/recipes/pyyaml/__init__.py | 6 +- kivy_ios/recipes/sdl2/__init__.py | 12 +- kivy_ios/recipes/sdl2_image/__init__.py | 10 +- kivy_ios/recipes/sdl2_mixer/__init__.py | 10 +- kivy_ios/recipes/sdl2_ttf/__init__.py | 8 +- kivy_ios/recipes/werkzeug/__init__.py | 6 +- kivy_ios/recipes/zbarlight/__init__.py | 15 +- kivy_ios/toolchain.py | 426 +++++++++++------- kivy_ios/tools/liblink | 7 +- .../project.pbxproj | 4 +- 36 files changed, 445 insertions(+), 349 deletions(-) diff --git a/.ci/constants.py b/.ci/constants.py index c130159ec..9e375b138 100644 --- a/.ci/constants.py +++ b/.ci/constants.py @@ -1,4 +1,4 @@ -BROKEN_RECIPES = set(["netifaces"]) +BROKEN_RECIPES = set(["netifaces", "zbarlight", "kivent_core"]) # recipes that were already built will be skipped CORE_RECIPES = set(["kivy", "hostpython3", "python3"]) diff --git a/kivy_ios/recipes/click/__init__.py b/kivy_ios/recipes/click/__init__.py index c2d2d59f4..2a390ef71 100644 --- a/kivy_ios/recipes/click/__init__.py +++ b/kivy_ios/recipes/click/__init__.py @@ -11,11 +11,11 @@ class ClickRecipe(PythonRecipe): depends = ["python"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python3") build_env['PYTHONPATH'] = self.ctx.site_packages_dir shprint(hostpython, "setup.py", "install", "--prefix", dest_dir, _env=build_env) diff --git a/kivy_ios/recipes/ffmpeg/__init__.py b/kivy_ios/recipes/ffmpeg/__init__.py index 3114d3353..a9a929929 100644 --- a/kivy_ios/recipes/ffmpeg/__init__.py +++ b/kivy_ios/recipes/ffmpeg/__init__.py @@ -6,7 +6,7 @@ class FFMpegRecipe(Recipe): version = "n4.4.2" url = "https://github.com/FFmpeg/FFmpeg/archive/{version}.zip" - include_per_arch = True + include_per_platform = True include_dir = "dist/include" optional_depends = ["openssl"] libraries = [ @@ -21,7 +21,7 @@ class FFMpegRecipe(Recipe): ] pbx_frameworks = ["VideoToolbox"] - def build_arch(self, arch): + def build_platform(self, plat): options = [ "--disable-everything", "--enable-parsers", @@ -57,12 +57,12 @@ def build_arch(self, arch): "--enable-nonfree", "--enable-protocol=https,tls_openssl"] - build_env = arch.get_env() + build_env = plat.get_env() build_env["VERBOSE"] = "1" configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, "--target-os=darwin", - "--arch={}".format(arch.arch), + "--arch={}".format(plat.arch), "--cc={}".format(build_env["CC"]), "--prefix={}/dist".format(self.build_dir), "--extra-cflags={}".format(build_env["CFLAGS"]), diff --git a/kivy_ios/recipes/ffpyplayer/__init__.py b/kivy_ios/recipes/ffpyplayer/__init__.py index 67f3c65df..8d76e3ca1 100644 --- a/kivy_ios/recipes/ffpyplayer/__init__.py +++ b/kivy_ios/recipes/ffpyplayer/__init__.py @@ -13,18 +13,18 @@ class FFPyplayerRecipe(CythonRecipe): pbx_libraries = ["libiconv"] pre_build_ext = True - def get_recipe_env(self, arch): - env = super(FFPyplayerRecipe, self).get_recipe_env(arch) + def get_recipe_env(self, plat): + env = super(FFPyplayerRecipe, self).get_recipe_env(plat) env["CC"] += " -I{}".format( - join(self.ctx.dist_dir, "include", arch.arch, "libffi")) + join(self.ctx.dist_dir, "include", plat.name, "libffi")) env["SDL_INCLUDE_DIR"] = join(self.ctx.dist_dir, "include", "common", "sdl2") env["FFMPEG_INCLUDE_DIR"] = join(self.ctx.dist_dir, "include", - arch.arch, "ffmpeg") + plat.name, "ffmpeg") env["CONFIG_POSTPROC"] = "0" return env - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): # common to all archs if self.has_marker("patched"): return diff --git a/kivy_ios/recipes/flask/__init__.py b/kivy_ios/recipes/flask/__init__.py index 8af56891f..e4c389714 100644 --- a/kivy_ios/recipes/flask/__init__.py +++ b/kivy_ios/recipes/flask/__init__.py @@ -11,11 +11,11 @@ class FlaskRecipe(PythonRecipe): depends = ["python", "jinja2", "werkzeug", "itsdangerous", "click"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python") build_env['PYTHONPATH'] = self.ctx.site_packages_dir shprint(hostpython, "setup.py", "install", "--prefix", dest_dir, _env=build_env) diff --git a/kivy_ios/recipes/freetype/__init__.py b/kivy_ios/recipes/freetype/__init__.py index ca537e346..f40486cec 100644 --- a/kivy_ios/recipes/freetype/__init__.py +++ b/kivy_ios/recipes/freetype/__init__.py @@ -8,10 +8,10 @@ class FreetypeRecipe(Recipe): url = "https://download.savannah.gnu.org/releases/freetype/freetype-old/freetype-{version}.tar.bz2" library = "objs/.libs/libfreetype.a" include_dir = ["include", ("builds/unix/ftconfig.h", "config/ftconfig.h")] - include_per_arch = True + include_per_platform = True - def build_arch(self, arch): - build_env = arch.get_env() + def build_platform(self, plat): + build_env = plat.get_env() configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, "CC={}".format(build_env["CC"]), @@ -19,7 +19,7 @@ def build_arch(self, arch): "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={}".format(build_env["LDFLAGS"]), "--prefix=/", - "--host={}".format(arch.triple), + "--host={}".format(plat.triple), "--without-png", "--without-bzip2", "--without-fsspec", diff --git a/kivy_ios/recipes/hostopenssl/__init__.py b/kivy_ios/recipes/hostopenssl/__init__.py index 04eed3d50..9a8f05819 100644 --- a/kivy_ios/recipes/hostopenssl/__init__.py +++ b/kivy_ios/recipes/hostopenssl/__init__.py @@ -18,24 +18,24 @@ def get_build_env(self): self.build_env = build_env return build_env - def build_arch(self, arch): + def build_platform(self, plat): build_env = self.get_build_env() configure = sh.Command(join(self.build_dir, "Configure")) shprint(configure, - arch_mapper[arch.arch], + arch_mapper[plat.arch], _env=build_env) shprint(sh.make, "clean") shprint(sh.make, self.ctx.concurrent_make, "build_libs") def install(self): - arch = self.archs[0] + plat = list(self.platforms_to_build)[0] sh.mkdir('-p', join(self.ctx.dist_dir, 'hostopenssl')) - sh.cp('-r', join(self.get_build_dir(arch), 'include'), + sh.cp('-r', join(self.get_build_dir(plat), 'include'), join(self.ctx.dist_dir, 'hostopenssl', 'include')) sh.mkdir('-p', join(self.ctx.dist_dir, 'hostopenssl', 'lib')) - sh.cp(join(self.get_build_dir(arch), 'libssl.a'), + sh.cp(join(self.get_build_dir(plat), 'libssl.a'), join(self.ctx.dist_dir, 'hostopenssl', 'lib')) - sh.cp(join(self.get_build_dir(arch), 'libcrypto.a'), + sh.cp(join(self.get_build_dir(plat), 'libcrypto.a'), join(self.ctx.dist_dir, 'hostopenssl', 'lib')) diff --git a/kivy_ios/recipes/hostpython3/__init__.py b/kivy_ios/recipes/hostpython3/__init__.py index b4aff88fb..d54b73e39 100644 --- a/kivy_ios/recipes/hostpython3/__init__.py +++ b/kivy_ios/recipes/hostpython3/__init__.py @@ -26,17 +26,17 @@ def init_with_ctx(self, ctx): logger.info("Global: hostpython located at {}".format(self.ctx.hostpython)) logger.info("Global: hostpgen located at {}".format(self.ctx.hostpgen)) - def get_build_subdir(self, arch): - return join(self.get_build_dir(arch), self.build_subdir) + def get_build_subdir(self, plat): + return join(self.get_build_dir(plat), self.build_subdir) - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("disable_sysconfig_cflags.patch") self.copy_file("ModulesSetup", "Modules/Setup.local") self.set_marker("patched") - def postbuild_arch(self, arch): + def postbuild_platform(self, plat): return def get_build_env(self): @@ -55,12 +55,12 @@ def get_build_env(self): ]) return build_env - def build_arch(self, arch): + def build_platform(self, plat): build_env = self.get_build_env() configure = sh.Command(join(self.build_dir, "configure")) - build_subdir = self.get_build_subdir(arch.arch) + build_subdir = self.get_build_subdir(plat) os.makedirs(build_subdir, exist_ok=True) with cd(build_subdir): @@ -75,9 +75,9 @@ def build_arch(self, arch): _env=build_env) def install(self): - arch = list(self.filtered_archs)[0] + plat = list(self.platforms_to_build)[0] build_env = self.get_build_env() - build_subdir = self.get_build_subdir(arch.arch) + build_subdir = self.get_build_subdir(plat) build_env["PATH"] = os.environ["PATH"] shprint(sh.make, self.ctx.concurrent_make, "-C", build_subdir, diff --git a/kivy_ios/recipes/itsdangerous/__init__.py b/kivy_ios/recipes/itsdangerous/__init__.py index 117d3a487..4157b9e31 100644 --- a/kivy_ios/recipes/itsdangerous/__init__.py +++ b/kivy_ios/recipes/itsdangerous/__init__.py @@ -11,10 +11,10 @@ class ItsDangerousRecipe(PythonRecipe): depends = ["python"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python3") build_env['PYTHONPATH'] = self.ctx.site_packages_dir with cd(build_dir): diff --git a/kivy_ios/recipes/jinja2/__init__.py b/kivy_ios/recipes/jinja2/__init__.py index 6df83889f..42ce1ffc2 100644 --- a/kivy_ios/recipes/jinja2/__init__.py +++ b/kivy_ios/recipes/jinja2/__init__.py @@ -11,11 +11,11 @@ class Jinja2Recipe(PythonRecipe): depends = ["python", "markupsafe"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python3") build_env['PYTHONPATH'] = self.ctx.site_packages_dir shprint(hostpython, "setup.py", "install", "--prefix", dest_dir, _env=build_env) diff --git a/kivy_ios/recipes/kivent_core/__init__.py b/kivy_ios/recipes/kivent_core/__init__.py index eba4202c4..2e0116d57 100644 --- a/kivy_ios/recipes/kivent_core/__init__.py +++ b/kivy_ios/recipes/kivent_core/__init__.py @@ -22,18 +22,18 @@ class KiventCoreRecipe(CythonRecipe): 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) + def get_recipe_env(self, plat): + env = super(KiventCoreRecipe, self).get_recipe_env(plat) env['CYTHONPATH'] = self.get_recipe( - 'kivy', self.ctx).get_build_dir(arch.arch) + 'kivy', self.ctx).get_build_dir(plat) return env - def get_build_dir(self, arch, sub=False): + def get_build_dir(self, plat, 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)) + builddir = super(KiventCoreRecipe, self).get_build_dir(plat) if sub or self.subbuilddir: core_build_dir = join(builddir, 'modules', 'core') logger.info("Core build directory is located at {}".format(core_build_dir)) @@ -42,7 +42,7 @@ def get_build_dir(self, arch, sub=False): logger.info("Building in {}".format(builddir)) return builddir - def build_arch(self, arch): + def build_platform(self, plat): """ Override build.arch to avoid calling setup.py here (Call it in install() instead). @@ -66,26 +66,26 @@ def install(self): Note: This method is called by build_all() in toolchain.py """ - arch = list(self.filtered_archs)[0] + plat = list(self.platforms_to_build)[0] - build_dir = self.get_build_dir(arch.arch, sub=True) - logger.info("Building kivent_core {} in {}".format(arch.arch, build_dir)) + build_dir = self.get_build_dir(plat, sub=True) + logger.info("Building kivent_core {} in {}".format(plat.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) + # build_env = plat.get_env() + build_env = self.get_recipe_env(plat) dest_dir = join(self.ctx.dist_dir, "root", "python") build_env['PYTHONPATH'] = join(dest_dir, 'lib', 'python3.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) + arch_kivy_path = self.get_recipe('kivy', self.ctx).get_build_dir(plat) 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) + subdir_path = self.get_build_dir(plat, sub=True) setup_path = join(subdir_path, "setup.py") # Print out directories for sanity check @@ -94,7 +94,7 @@ def install(self): logger.info("BUILD", self.ctx.build_dir) logger.info("INCLUDE", self.ctx.include_dir) logger.info("DISTDIR", self.ctx.dist_dir) - logger.info("ARCH KIVY LOC", self.get_recipe('kivy', self.ctx).get_build_dir(arch.arch)) + logger.info("ARCH KIVY LOC", self.get_recipe('kivy', self.ctx).get_build_dir(plat)) shprint(hostpython, setup_path, "build_ext", "install", _env=build_env) diff --git a/kivy_ios/recipes/kivy/__init__.py b/kivy_ios/recipes/kivy/__init__.py index 14793273a..98272fed3 100644 --- a/kivy_ios/recipes/kivy/__init__.py +++ b/kivy_ios/recipes/kivy/__init__.py @@ -16,8 +16,8 @@ class KivyRecipe(CythonRecipe): pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"] pre_build_ext = True - def get_recipe_env(self, arch): - env = super().get_recipe_env(arch) + def get_recipe_env(self, plat): + env = super().get_recipe_env(plat) env["KIVY_SDL2_PATH"] = ":".join([ join(self.ctx.dist_dir, "include", "common", "sdl2"), join(self.ctx.dist_dir, "include", "common", "sdl2_image"), @@ -25,9 +25,9 @@ def get_recipe_env(self, arch): join(self.ctx.dist_dir, "include", "common", "sdl2_mixer")]) return env - def build_arch(self, arch): + def build_platform(self, plat): self._patch_setup() - super().build_arch(arch) + super().build_platform(plat) def _patch_setup(self): # patch setup to remove some functionnalities diff --git a/kivy_ios/recipes/libcurl/__init__.py b/kivy_ios/recipes/libcurl/__init__.py index 37ebfec6d..855ce1689 100644 --- a/kivy_ios/recipes/libcurl/__init__.py +++ b/kivy_ios/recipes/libcurl/__init__.py @@ -4,14 +4,14 @@ class CurlRecipe(Recipe): - version = "7.65.3" + version = "7.88.1" url = "https://curl.haxx.se/download/curl-{version}.tar.gz" library = "lib/.libs/libcurl.a" include_dir = "include" depends = ["openssl"] - def build_arch(self, arch): - build_env = arch.get_env() + def build_platform(self, plat): + build_env = plat.get_env() configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, "CC={}".format(build_env["CC"]), @@ -19,9 +19,10 @@ def build_arch(self, arch): "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={}".format(build_env["LDFLAGS"]), "--prefix=/", - "--host={}".format(arch.triple), + "--host={}".format(plat.triple), "--disable-shared", - "--without-libidn2") + "--without-libidn2", + "--with-openssl") shprint(sh.make, "clean") shprint(sh.make, self.ctx.concurrent_make) diff --git a/kivy_ios/recipes/libffi/__init__.py b/kivy_ios/recipes/libffi/__init__.py index 6aa295611..14403d98f 100644 --- a/kivy_ios/recipes/libffi/__init__.py +++ b/kivy_ios/recipes/libffi/__init__.py @@ -4,15 +4,14 @@ class LibffiRecipe(Recipe): - version = "3.4.2" + version = "3.4.4" url = "https://github.com/libffi/libffi/releases/download/v{version}/libffi-{version}.tar.gz" - library = "build/Release-{arch.sdk}/libffi.a" - include_per_arch = True - include_dir = "build_{arch.sdk}-{arch.arch}/include" + library = "build/Release-{plat.sdk}/libffi.a" + include_per_platform = True + include_dir = "build_{plat.name}/include" include_name = "ffi" - archs = ["x86_64", "arm64"] - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("enable-tramp-build.patch") @@ -26,7 +25,7 @@ def prebuild_arch(self, arch): "generate-darwin-source-and-headers.py") self.set_marker("patched") - def build_arch(self, arch): + def build_platform(self, plat): if exists("generate-darwin-source-and-headers.py"): shprint( sh.mv, @@ -37,9 +36,9 @@ def build_arch(self, arch): shprint(python3, "_generate-darwin-source-and-headers.py", "--only-ios") shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, "ONLY_ACTIVE_ARCH=NO", - "ARCHS={}".format(arch.arch), + "ARCHS={}".format(plat.arch), "BITCODE_GENERATION_MODE=bitcode", - "-sdk", arch.sdk, + "-sdk", plat.sdk, "-project", "libffi.xcodeproj", "-target", "libffi-iOS", "-configuration", "Release") diff --git a/kivy_ios/recipes/libjpeg/__init__.py b/kivy_ios/recipes/libjpeg/__init__.py index 6c508d371..b34d87c7e 100644 --- a/kivy_ios/recipes/libjpeg/__init__.py +++ b/kivy_ios/recipes/libjpeg/__init__.py @@ -13,10 +13,10 @@ class JpegRecipe(Recipe): ("jerror.h", ""), ("jmorecfg.h", ""), ] - include_per_arch = True + include_per_platform = True - def build_arch(self, arch): - build_env = arch.get_env() + def build_platform(self, plat): + build_env = plat.get_env() configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, "CC={}".format(build_env["CC"]), @@ -24,7 +24,7 @@ def build_arch(self, arch): "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={}".format(build_env["LDFLAGS"]), "--prefix=/", - "--host={}".format(arch.triple), + "--host={}".format(plat.triple), "--disable-shared") shprint(sh.make, "clean") shprint(sh.make, self.ctx.concurrent_make) diff --git a/kivy_ios/recipes/libpng/__init__.py b/kivy_ios/recipes/libpng/__init__.py index 3d20dba96..87705f0c2 100644 --- a/kivy_ios/recipes/libpng/__init__.py +++ b/kivy_ios/recipes/libpng/__init__.py @@ -10,8 +10,8 @@ class PngRecipe(Recipe): library = 'dist/lib/libpng16.a' include_dir = 'dist/include' - def build_arch(self, arch): - build_env = arch.get_env() + def build_platform(self, plat): + build_env = plat.get_env() configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, @@ -20,7 +20,7 @@ def build_arch(self, arch): "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={}".format(build_env["LDFLAGS"]), "--prefix={}".format(join(self.build_dir, "dist")), - "--host={}".format(arch.triple), + "--host={}".format(plat.triple), "--disable-shared") shprint(sh.make, "clean") shprint(sh.make, self.ctx.concurrent_make, _env=build_env) diff --git a/kivy_ios/recipes/libzbar/__init__.py b/kivy_ios/recipes/libzbar/__init__.py index 4c4d6c663..1c496805c 100755 --- a/kivy_ios/recipes/libzbar/__init__.py +++ b/kivy_ios/recipes/libzbar/__init__.py @@ -13,23 +13,23 @@ class LibZBarRecipe(Recipe): library = 'zbar/.libs/libzbar.a' - include_per_arch = True + include_per_platform = True include_dir = [ ("include", "") ] - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("werror.patch") self.set_marker("patched") - def build_arch(self, arch): - super(LibZBarRecipe, self).build_arch(arch) - build_env = arch.get_env() + def build_platform(self, plat): + super(LibZBarRecipe, self).build_platform(plat) + build_env = plat.get_env() build_env["CFLAGS"] = " ".join([ - "-I{}".format(join(self.ctx.dist_dir, "build", "libiconv", arch.arch)) + - " -arch {}".format(arch.arch), build_env['CFLAGS'] + "-I{}".format(join(self.ctx.dist_dir, "build", "libiconv", plat.name)) + + " -arch {}".format(plat.arch), build_env['CFLAGS'] ]) shprint(sh.Command('autoreconf'), '-vif') shprint( @@ -38,8 +38,8 @@ def build_arch(self, arch): "LD={}".format(build_env["LD"]), "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={}".format(build_env["LDFLAGS"]), - "--host={}".format(arch.triple), - '--target={}'.format(arch.triple), + "--host={}".format(plat.triple), + '--target={}'.format(plat.triple), # Python bindings are compiled in a separated recipe '--with-python=no', '--with-gtk=no', diff --git a/kivy_ios/recipes/markupsafe/__init__.py b/kivy_ios/recipes/markupsafe/__init__.py index 6f9c8e133..4140c47dc 100644 --- a/kivy_ios/recipes/markupsafe/__init__.py +++ b/kivy_ios/recipes/markupsafe/__init__.py @@ -11,11 +11,11 @@ class MarkupSafeRecipe(PythonRecipe): depends = ["python"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python3") build_env['PYTHONPATH'] = self.ctx.site_packages_dir cmd = sh.Command("sed") diff --git a/kivy_ios/recipes/netifaces/__init__.py b/kivy_ios/recipes/netifaces/__init__.py index 68faa1aa0..3276e0ac4 100644 --- a/kivy_ios/recipes/netifaces/__init__.py +++ b/kivy_ios/recipes/netifaces/__init__.py @@ -17,15 +17,15 @@ class NetifacesRecipe(CythonRecipe): def dest_dir(self): return join(self.ctx.dist_dir, "root", "python3") - def get_netifaces_env(self, arch): - build_env = arch.get_env() + def get_netifaces_env(self, plat): + build_env = plat.get_env() build_env["PYTHONPATH"] = self.ctx.site_packages_dir return build_env def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) - build_env = self.get_netifaces_env(arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) + build_env = self.get_netifaces_env(plat) hostpython = sh.Command(self.ctx.hostpython) with cd(build_dir): shprint( diff --git a/kivy_ios/recipes/numpy/__init__.py b/kivy_ios/recipes/numpy/__init__.py index 203be2822..339059d00 100644 --- a/kivy_ios/recipes/numpy/__init__.py +++ b/kivy_ios/recipes/numpy/__init__.py @@ -14,15 +14,15 @@ class NumpyRecipe(CythonRecipe): hostpython_prerequisites = ["Cython==0.29.36"] cythonize = False - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("skip-math-test.patch") self.apply_patch("duplicated_symbols.patch") self.set_marker("patched") - def get_recipe_env(self, arch): - env = super().get_recipe_env(arch) + def get_recipe_env(self, plat): + env = super().get_recipe_env(plat) # CC must have the CFLAGS with arm arch, because numpy tries first to # compile and execute an empty C to see if the compiler works. This is # obviously not working when crosscompiling @@ -32,8 +32,8 @@ def get_recipe_env(self, arch): env["NPY_LAPACK_ORDER"] = "" return env - def build_arch(self, arch): - super().build_arch(arch) + def build_platform(self, plat): + super().build_platform(plat) sh.cp(sh.glob(join(self.build_dir, "build", "temp.*", "libnpy*.a")), self.build_dir) diff --git a/kivy_ios/recipes/openssl/__init__.py b/kivy_ios/recipes/openssl/__init__.py index 171f0d9a4..60e6919f6 100644 --- a/kivy_ios/recipes/openssl/__init__.py +++ b/kivy_ios/recipes/openssl/__init__.py @@ -3,8 +3,11 @@ import sh -arch_mapper = {'x86_64': 'darwin64-x86_64-cc', - 'arm64': 'ios64-cross'} +plat_mapper = { + 'iphoneos-arm64': 'ios64-xcrun', + 'iphonesimulator-x86_64': 'iossimulator-xcrun', + 'iphonesimulator-arm64': 'iossimulator-xcrun', +} class OpensslRecipe(Recipe): @@ -12,21 +15,13 @@ class OpensslRecipe(Recipe): url = "http://www.openssl.org/source/openssl-{version}.tar.gz" libraries = ["libssl.a", "libcrypto.a"] include_dir = "include" - include_per_arch = True + include_per_platform = True - def build_arch(self, arch): - build_env = arch.get_env() - target = arch_mapper[arch.arch] + def build_platform(self, plat): + build_env = plat.get_env() + target = plat_mapper[plat.name] shprint(sh.env, _env=build_env) - sh.perl(join(self.build_dir, "Configure"), - target, - _env=build_env) - if target.endswith('-cross'): - with open('Makefile', 'r') as makefile: - filedata = makefile.read() - filedata = filedata.replace('$(CROSS_TOP)/SDKs/$(CROSS_SDK)', arch.sysroot) - with open('Makefile', 'w') as makefile: - makefile.write(filedata) + sh.perl(join(self.build_dir, "Configure"), target, _env=build_env) shprint(sh.make, "clean") shprint(sh.make, self.ctx.concurrent_make, "build_libs") diff --git a/kivy_ios/recipes/pillow/__init__.py b/kivy_ios/recipes/pillow/__init__.py index 39cc75ff8..b91e0f3d6 100644 --- a/kivy_ios/recipes/pillow/__init__.py +++ b/kivy_ios/recipes/pillow/__init__.py @@ -17,26 +17,26 @@ class PillowRecipe(CythonRecipe): ] python_depends = ["setuptools"] pbx_libraries = ["libz", "libbz2"] - include_per_arch = True + include_per_platform = True cythonize = False - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("bypass-find-library.patch") self.set_marker("patched") - def get_recipe_env(self, arch): - env = super().get_recipe_env(arch) - env["C_INCLUDE_PATH"] = join(arch.sysroot, "usr", "include") - env["LIBRARY_PATH"] = join(arch.sysroot, "usr", "lib") + def get_recipe_env(self, plat): + env = super().get_recipe_env(plat) + env["C_INCLUDE_PATH"] = join(plat.sysroot, "usr", "include") + env["LIBRARY_PATH"] = join(plat.sysroot, "usr", "lib") env["CFLAGS"] += " ".join( [ - " -I{}".format(join(self.ctx.dist_dir, "include", arch.arch, "freetype")) + " -I{}".format(join(self.ctx.dist_dir, "include", plat.name, "freetype")) + " -I{}".format( - join(self.ctx.dist_dir, "include", arch.arch, "libjpeg") + join(self.ctx.dist_dir, "include", plat.name, "libjpeg") ) - + " -arch {}".format(arch.arch) + + " -arch {}".format(plat.arch) ] ) env["PATH"] = os.environ["PATH"] @@ -45,8 +45,8 @@ def get_recipe_env(self, arch): ] = "ios-pkg-config" # ios-pkg-config does not exists, is needed to disable the pkg-config usage. return env - def build_arch(self, arch): - build_env = self.get_recipe_env(arch) + def build_platform(self, plat): + build_env = self.get_recipe_env(plat) hostpython3 = sh.Command(self.ctx.hostpython) shprint( hostpython3, diff --git a/kivy_ios/recipes/plyer/__init__.py b/kivy_ios/recipes/plyer/__init__.py index bbe8552e5..9f8411370 100644 --- a/kivy_ios/recipes/plyer/__init__.py +++ b/kivy_ios/recipes/plyer/__init__.py @@ -5,7 +5,6 @@ class PlyerRecipe(PythonRecipe): version = "master" url = "https://github.com/kivy/plyer/archive/{version}.zip" depends = ["python", "pyobjus"] - archs = ["x86_64"] recipe = PlyerRecipe() diff --git a/kivy_ios/recipes/py3dns/__init__.py b/kivy_ios/recipes/py3dns/__init__.py index fea425c4e..8340062ef 100644 --- a/kivy_ios/recipes/py3dns/__init__.py +++ b/kivy_ios/recipes/py3dns/__init__.py @@ -8,7 +8,7 @@ class Py3DNSRecipe(PythonRecipe): '+download/py3dns-{version}.tar.gz' depends = ['python3'] - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return diff --git a/kivy_ios/recipes/pycrypto/__init__.py b/kivy_ios/recipes/pycrypto/__init__.py index 3c49c199b..b155a4b87 100644 --- a/kivy_ios/recipes/pycrypto/__init__.py +++ b/kivy_ios/recipes/pycrypto/__init__.py @@ -10,11 +10,11 @@ class PycryptoRecipe(CythonRecipe): version = "2.6.1" url = "https://ftp.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-{version}.tar.gz" depends = ["python", "openssl"] - include_per_arch = True + include_per_platform = True library = "libpycrypto.a" - def build_arch(self, arch): - build_env = arch.get_env() + def build_platform(self, plat): + build_env = plat.get_env() self.apply_patch('hash_SHA2_template.c.patch', target_dir=self.build_dir + '/src') configure = sh.Command(join(self.build_dir, "configure")) shprint(configure, @@ -23,16 +23,16 @@ def build_arch(self, arch): "CFLAGS={}".format(build_env["CFLAGS"]), "LDFLAGS={} -Wno-error ".format(build_env["LDFLAGS"]), "--prefix=/", - "--host={}".format(arch), + "--host={}".format(plat), "ac_cv_func_malloc_0_nonnull=yes", "ac_cv_func_realloc_0_nonnull=yes") - super(PycryptoRecipe, self).build_arch(arch) + super(PycryptoRecipe, self).build_platform(plat) def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python") build_env['PYTHONPATH'] = join(dest_dir, 'lib', 'python3.7', 'site-packages') with cd(build_dir): diff --git a/kivy_ios/recipes/python3/__init__.py b/kivy_ios/recipes/python3/__init__.py index cc603baeb..2d1987474 100644 --- a/kivy_ios/recipes/python3/__init__.py +++ b/kivy_ios/recipes/python3/__init__.py @@ -23,7 +23,7 @@ def init_with_ctx(self, ctx): ctx.site_packages_dir = join( ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages") - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): # common to all archs if self.has_marker("patched"): return @@ -35,23 +35,23 @@ def prebuild_arch(self, arch): self.append_file("ModulesSetup.mobile", "Modules/Setup.local") self.set_marker("patched") - def postbuild_arch(self, arch): + def postbuild_platform(self, plat): # We need to skip remove_junk, because we need to keep few files. # A cleanup will be done in the final step. return - def get_build_env(self, arch): - build_env = arch.get_env() + def get_build_env(self, plat): + build_env = plat.get_env() build_env["PATH"] = "{}:{}".format( join(self.ctx.dist_dir, "hostpython3", "bin"), os.environ["PATH"]) - build_env["CFLAGS"] += " --sysroot={}".format(arch.sysroot) + build_env["CFLAGS"] += " --sysroot={}".format(plat.sysroot) return build_env - def build_arch(self, arch): - build_env = self.get_build_env(arch) + def build_platform(self, plat): + build_env = self.get_build_env(plat) configure = sh.Command(join(self.build_dir, "configure")) - py_arch = arch.arch + py_arch = plat.arch if py_arch == "arm64": py_arch = "aarch64" prefix = join(self.ctx.dist_dir, "root", "python3") @@ -114,9 +114,9 @@ def build_arch(self, arch): shprint(sh.make, self.ctx.concurrent_make, "CFLAGS={}".format(build_env["CFLAGS"])) def install(self): - arch = list(self.filtered_archs)[0] - build_env = self.get_build_env(arch) - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_env = self.get_build_env(plat) + build_dir = self.get_build_dir(plat) shprint(sh.make, self.ctx.concurrent_make, "-C", build_dir, "install", diff --git a/kivy_ios/recipes/pyyaml/__init__.py b/kivy_ios/recipes/pyyaml/__init__.py index c2be8191b..ad9b3717a 100644 --- a/kivy_ios/recipes/pyyaml/__init__.py +++ b/kivy_ios/recipes/pyyaml/__init__.py @@ -10,11 +10,11 @@ class PyYamlRecipe(PythonRecipe): depends = ["python"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = os.path.join(self.ctx.dist_dir, "root", "python") build_env['PYTHONPATH'] = os.path.join(dest_dir, 'lib', 'python3.7', 'site-packages') shprint(hostpython, "setup.py", "install", "--prefix", dest_dir, _env=build_env) diff --git a/kivy_ios/recipes/sdl2/__init__.py b/kivy_ios/recipes/sdl2/__init__.py index 9009e209f..5b7983ce9 100644 --- a/kivy_ios/recipes/sdl2/__init__.py +++ b/kivy_ios/recipes/sdl2/__init__.py @@ -5,28 +5,28 @@ class LibSDL2Recipe(Recipe): version = "2.24.1" url = "https://github.com/libsdl-org/SDL/releases/download/release-{version}/SDL2-{version}.tar.gz" - library = "Xcode/SDL/build/Release-{arch.sdk}/libSDL2.a" + library = "Xcode/SDL/build/Release-{plat.sdk}/libSDL2.a" include_dir = "include" pbx_frameworks = [ "OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics", "CoreMotion", "GameController", "AVFoundation", "Metal", "UIKit", "CoreHaptics"] - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return self.apply_patch("uikit-transparent.patch") self.apply_patch("disable-hidapi.patch") self.set_marker("patched") - def build_arch(self, arch): - env = arch.get_env() + def build_platform(self, plat): + env = plat.get_env() shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, "ONLY_ACTIVE_ARCH=NO", - "ARCHS={}".format(arch.arch), + "ARCHS={}".format(plat.arch), "BITCODE_GENERATION_MODE=bitcode", "CC={}".format(env['CC']), - "-sdk", arch.sdk, + "-sdk", plat.sdk, "-project", "Xcode/SDL/SDL.xcodeproj", "-target", "Static Library-iOS", "-configuration", "Release") diff --git a/kivy_ios/recipes/sdl2_image/__init__.py b/kivy_ios/recipes/sdl2_image/__init__.py index b4ee0b34b..58256c111 100644 --- a/kivy_ios/recipes/sdl2_image/__init__.py +++ b/kivy_ios/recipes/sdl2_image/__init__.py @@ -6,12 +6,12 @@ class LibSDL2ImageRecipe(Recipe): version = "2.6.2" url = "https://github.com/libsdl-org/SDL_image/releases/download/release-{version}/SDL2_image-{version}.tar.gz" - library = "Xcode/build/Release-{arch.sdk}/libSDL2_image.a" + library = "Xcode/build/Release-{plat.sdk}/libSDL2_image.a" include_dir = "SDL_image.h" depends = ["sdl2"] pbx_frameworks = ["CoreGraphics", "MobileCoreServices"] - def prebuild_arch(self, arch): + def prebuild_platform(self, plat): if self.has_marker("patched"): return # fix-ios-xcodebuild is a patch taken from the SDL2_image repo @@ -20,14 +20,14 @@ def prebuild_arch(self, arch): self.apply_patch("fix-ios-xcodebuild.patch") self.set_marker("patched") - def build_arch(self, arch): + def build_platform(self, plat): shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, "ONLY_ACTIVE_ARCH=NO", - "ARCHS={}".format(arch.arch), + "ARCHS={}".format(plat.arch), "BITCODE_GENERATION_MODE=bitcode", "HEADER_SEARCH_PATHS={}".format( join(self.ctx.include_dir, "common", "sdl2")), - "-sdk", arch.sdk, + "-sdk", plat.sdk, "-project", "Xcode/SDL_image.xcodeproj", "-target", "Static Library", "-configuration", "Release") diff --git a/kivy_ios/recipes/sdl2_mixer/__init__.py b/kivy_ios/recipes/sdl2_mixer/__init__.py index 47656701c..76fae73ca 100644 --- a/kivy_ios/recipes/sdl2_mixer/__init__.py +++ b/kivy_ios/recipes/sdl2_mixer/__init__.py @@ -5,22 +5,22 @@ class LibSDL2MixerRecipe(Recipe): version = "2.6.2" url = "https://github.com/libsdl-org/SDL_mixer/releases/download/release-{version}/SDL2_mixer-{version}.tar.gz" - library = "Xcode/build/Release-{arch.sdk}/libSDL2_mixer.a" + library = "Xcode/build/Release-{plat.sdk}/libSDL2_mixer.a" include_dir = "include/SDL_mixer.h" depends = ["sdl2"] pbx_frameworks = ["ImageIO"] pbx_libraries = ["libc++"] - def build_arch(self, arch): + def build_platform(self, plat): # endian.h is in /usr/include/machine/ (Since MacOs Mojave?) # header is needed by libvorbis, so We're adding that folder # to HEADER_SEARCH_PATHS shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, "ONLY_ACTIVE_ARCH=NO", - "ARCHS={}".format(arch.arch), + "ARCHS={}".format(plat.arch), "BITCODE_GENERATION_MODE=bitcode", - "HEADER_SEARCH_PATHS=$HEADER_SEARCH_PATHS /usr/include/machine {} ".format(" ".join(arch.include_dirs)), - "-sdk", arch.sdk, + "HEADER_SEARCH_PATHS=$HEADER_SEARCH_PATHS /usr/include/machine {} ".format(" ".join(plat.include_dirs)), + "-sdk", plat.sdk, "-project", "Xcode/SDL_mixer.xcodeproj", "-target", "Static Library", "-configuration", "Release") diff --git a/kivy_ios/recipes/sdl2_ttf/__init__.py b/kivy_ios/recipes/sdl2_ttf/__init__.py index 16a945fa5..fa0352cf2 100644 --- a/kivy_ios/recipes/sdl2_ttf/__init__.py +++ b/kivy_ios/recipes/sdl2_ttf/__init__.py @@ -6,14 +6,14 @@ class LibSDL2TTFRecipe(Recipe): version = "2.20.2" url = "https://github.com/libsdl-org/SDL_ttf/releases/download/release-{version}/SDL2_ttf-{version}.tar.gz" - library = "Xcode/build/Release-{arch.sdk}/libSDL2_ttf.a" + library = "Xcode/build/Release-{plat.sdk}/libSDL2_ttf.a" include_dir = "SDL_ttf.h" depends = ["libpng", "sdl2"] - def build_arch(self, arch): + def build_platform(self, plat): shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild, "ONLY_ACTIVE_ARCH=NO", - "ARCHS={}".format(arch.arch), + "ARCHS={}".format(plat.arch), "BITCODE_GENERATION_MODE=bitcode", "GENERATE_MASTER_OBJECT_FILE=YES", "HEADER_SEARCH_PATHS={sdl_include_dir} {libpng_include_dir}".format( @@ -21,7 +21,7 @@ def build_arch(self, arch): libpng_include_dir=join(self.ctx.include_dir, "common", "libpng"), ), "GCC_PREPROCESSOR_DEFINITIONS=$(GCC_PREPROCESSOR_DEFINITIONS) FT_CONFIG_OPTION_USE_PNG=1", - "-sdk", arch.sdk, + "-sdk", plat.sdk, "-project", "Xcode/SDL_ttf.xcodeproj", "-target", "Static Library", "-configuration", "Release") diff --git a/kivy_ios/recipes/werkzeug/__init__.py b/kivy_ios/recipes/werkzeug/__init__.py index 401cb15c7..93f46b63f 100644 --- a/kivy_ios/recipes/werkzeug/__init__.py +++ b/kivy_ios/recipes/werkzeug/__init__.py @@ -11,11 +11,11 @@ class WerkzeugRecipe(PythonRecipe): depends = ["python", "openssl"] def install(self): - arch = list(self.filtered_archs)[0] - build_dir = self.get_build_dir(arch.arch) + plat = list(self.platforms_to_build)[0] + build_dir = self.get_build_dir(plat) os.chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) - build_env = arch.get_env() + build_env = plat.get_env() dest_dir = join(self.ctx.dist_dir, "root", "python3") build_env['PYTHONPATH'] = self.ctx.site_packages_dir shprint(hostpython, "setup.py", "install", "--prefix", dest_dir, _env=build_env) diff --git a/kivy_ios/recipes/zbarlight/__init__.py b/kivy_ios/recipes/zbarlight/__init__.py index 1f172efc5..d503d0454 100755 --- a/kivy_ios/recipes/zbarlight/__init__.py +++ b/kivy_ios/recipes/zbarlight/__init__.py @@ -13,26 +13,25 @@ class ZbarLightRecipe(Recipe): library = "zbarlight.a" depends = ["hostpython3", "python3", "libzbar"] pbx_libraries = ["libz", "libbz2", "libc++", "libsqlite3", "CoreMotion"] - include_per_arch = True + include_per_platform = True - def get_zbar_env(self, arch): - build_env = arch.get_env() - build_env["ARCH"] = arch.arch + def get_zbar_env(self, plat): + build_env = plat.get_env() + build_env["ARCH"] = plat.arch build_env["ARM_LD"] = build_env["LD"] build_env["LDSHARED"] = join(self.ctx.root_dir, "tools", "liblink") return build_env - def build_arch(self, arch): - build_env = self.get_zbar_env(arch) + def build_platform(self, plat): + build_env = self.get_zbar_env(plat) hostpython = sh.Command(self.ctx.hostpython) self.apply_patch("zbarlight_hardcode_version.patch") shprint(hostpython, "setup.py", "build", _env=build_env) self.biglink() def install(self): - arch = self.filtered_archs[0].arch source = next(pathlib.Path( - self.get_build_dir(arch), + self.get_build_dir(list(self.platforms_to_build)[0]), "build" ).glob("lib.*")) / "zbarlight" destination = next(pathlib.Path( diff --git a/kivy_ios/toolchain.py b/kivy_ios/toolchain.py index 456703a5a..471755e2f 100755 --- a/kivy_ios/toolchain.py +++ b/kivy_ios/toolchain.py @@ -136,30 +136,46 @@ def sync(self): json.dump(self.data, fd, ensure_ascii=False) -class Arch: +class GenericPlatform: + sdk = "unspecified" + arch = "unspecified" + version_min = "unspecified" + def __init__(self, ctx): self.ctx = ctx self._ccsh = None + @property + def name(self): + return f"{self.sdk}-{self.arch}" + def __str__(self): - return self.arch + return self.name + + @property + def sysroot(self): + return sh.xcrun("--sdk", self.sdk, "--show-sdk-path").strip() @property def include_dirs(self): return [ "{}/{}".format( self.ctx.include_dir, - d.format(arch=self)) + d.format(plat=self)) for d in self.ctx.include_dirs] + @property + def lib_dirs(self): + return [join(self.ctx.dist_dir, "lib", self.sdk)] + def get_env(self): include_dirs = [ "-I{}/{}".format( self.ctx.include_dir, - d.format(arch=self)) + d.format(plat=self)) for d in self.ctx.include_dirs] include_dirs += ["-I{}".format( - join(self.ctx.dist_dir, "include", self.arch))] + join(self.ctx.dist_dir, "include", self.name))] env = {} cc = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip() @@ -219,39 +235,61 @@ def get_env(self): 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) - env["OTHER_LDFLAGS"] = " ".join([ - "-L{}/{}".format(self.ctx.dist_dir, "lib"), - ]) + env["OTHER_LDFLAGS"] = " ".join([f"-L{d}" for d in self.lib_dirs]) env["CFLAGS"] = " ".join([ "-O3", - self.version_min + self.version_min, ] + include_dirs) if self.sdk == "iphoneos": env["CFLAGS"] += " -fembed-bitcode" env["LDFLAGS"] = " ".join([ "-arch", self.arch, # "--sysroot", self.sysroot, - "-L{}/{}".format(self.ctx.dist_dir, "lib"), + *[f"-L{d}" for d in self.lib_dirs], "-L{}/usr/lib".format(self.sysroot), self.version_min ]) return env -class Arch64Simulator(Arch): +class iPhoneSimulatorPlatform(GenericPlatform): sdk = "iphonesimulator" + version_min = "-miphonesimulator-version-min=9.0" + + +class iPhoneOSPlatform(GenericPlatform): + sdk = "iphoneos" + version_min = "-miphoneos-version-min=9.0" + + +class macOSPlatform(GenericPlatform): + sdk = "macosx" + version_min = "-mmacosx-version-min=10.9" + + +class iPhoneSimulatorARM64Platform(iPhoneSimulatorPlatform): + arch = "arm64" + triple = "aarch64-apple-darwin13" + + +class iPhoneSimulatorx86_64Platform(iPhoneSimulatorPlatform): arch = "x86_64" triple = "x86_64-apple-darwin13" - version_min = "-miphoneos-version-min=9.0" - sysroot = sh.xcrun("--sdk", "iphonesimulator", "--show-sdk-path").strip() -class Arch64IOS(Arch): - sdk = "iphoneos" +class iPhoneOSARM64Platform(iPhoneOSPlatform): + arch = "arm64" + triple = "aarch64-apple-darwin13" + + +class macOSx86_64Platform(macOSPlatform): + arch = "x86_64" + triple = "x86_64-apple-darwin13" + + +class macOSARM64Platform(macOSPlatform): arch = "arm64" triple = "aarch64-apple-darwin13" - version_min = "-miphoneos-version-min=9.0" - sysroot = sh.xcrun("--sdk", "iphoneos", "--show-sdk-path").strip() class Graph: @@ -351,9 +389,29 @@ def __init__(self): self.dist_dir = "{}/dist".format(initial_working_directory) self.install_dir = "{}/dist/root".format(initial_working_directory) self.include_dir = "{}/dist/include".format(initial_working_directory) - self.archs = ( - Arch64Simulator(self), - Arch64IOS(self)) + + # Supported platforms may differ from default ones, + # and the user may select to build only a subset of them via + # --platforms command line argument. + self.supported_platforms = [ + iPhoneOSARM64Platform(self), + iPhoneSimulatorARM64Platform(self), + iPhoneSimulatorx86_64Platform(self), + ] + + # By default build the following platforms: + # - iPhoneOSARM64Platform* (arm64) + # - iPhoneOSSimulator*Platform (arm64 or x86_64), depending on the host + self.default_platforms = [iPhoneOSARM64Platform(self)] + if platform.machine() == "x86_64": + # Intel Mac, build for iPhoneOSSimulatorx86_64Platform + self.default_platforms.append(iPhoneSimulatorx86_64Platform(self)) + elif platform.machine() == "arm64": + # Apple Silicon Mac, build for iPhoneOSSimulatorARM64Platform + self.default_platforms.append(iPhoneSimulatorARM64Platform(self)) + + # If the user didn't specify a platform, use the default ones. + self.selected_platforms = self.default_platforms # path to some tools self.ccache = shutil.which("ccache") @@ -418,14 +476,14 @@ class Recipe: "is_alias": False, "version": None, "url": None, - "archs": [], + "supported_platforms": ["iphoneos-arm64", "iphonesimulator-x86_64", "iphonesimulator-arm64"], "depends": [], "optional_depends": [], "python_depends": [], "library": None, "libraries": [], "include_dir": None, - "include_per_arch": False, + "include_per_platform": False, "include_name": None, "frameworks": [], "sources": [], @@ -607,29 +665,19 @@ def archive_fn(self): return fn @property - def filtered_archs(self): - result = [] - for arch in self.ctx.archs: - if not self.archs or (arch.arch in self.archs): - result.append(arch) - return result + def platforms_to_build(self): + for selected_platform in self.ctx.selected_platforms: + if selected_platform.name in self.supported_platforms: + yield selected_platform @property - def dist_libraries(self): - libraries = [] - name = self.name - if not name.startswith("lib"): - name = "lib{}".format(name) - if self.library: - static_fn = join(self.ctx.dist_dir, "lib", "{}.a".format(name)) - libraries.append(static_fn) - for library in self.libraries: - static_fn = join(self.ctx.dist_dir, "lib", basename(library)) - libraries.append(static_fn) - return libraries + def dist_xcframeworks(self): + for lib in self._get_all_libraries(): + lib_name = basename(lib).split(".a")[0] + yield join(self.ctx.dist_dir, "xcframework", f"{lib_name}.xcframework") - def get_build_dir(self, arch): - return join(self.ctx.build_dir, self.name, arch, self.archive_root) + def get_build_dir(self, plat): + return join(self.ctx.build_dir, self.name, plat.name, self.archive_root) # Public Recipe API to be subclassed if needed @@ -638,20 +686,20 @@ def init_with_ctx(self, 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}", include_name) + if self.include_per_platform: + include_dir = join("{plat.name}", include_name) else: include_dir = join("common", include_name) if include_dir: logger.info("Include dir added: {}".format(include_dir)) self.ctx.include_dirs.append(include_dir) - def get_recipe_env(self, arch=None): + def get_recipe_env(self, plat=None): """Return the env specialized for the recipe """ - if arch is None: - arch = self.filtered_archs[0] - return arch.get_env() + if plat is None: + plat = list(self.platforms_to_build)[0] + return plat.get_env() def set_hostpython(self, instance, version): state = self.ctx.state @@ -740,12 +788,12 @@ def download(self): @cache_execution def extract(self): # recipe tmp directory - for arch in self.filtered_archs: - logger.info("Extract {} for {}".format(self.name, arch.arch)) - self.extract_arch(arch.arch) + for plat in self.platforms_to_build: + logger.info("Extract {} for {}".format(self.name, plat.name)) + self.extract_platform(plat) - def extract_arch(self, arch): - build_dir = join(self.ctx.build_dir, self.name, arch) + def extract_platform(self, plat): + build_dir = join(self.ctx.build_dir, self.name, plat.name) dest_dir = join(build_dir, self.archive_root) if self.custom_dir: shutil.rmtree(dest_dir, ignore_errors=True) @@ -766,56 +814,45 @@ def install_hostpython_prerequisites(self): _hostpython_pip(["install", prerequisite]) @cache_execution - def build(self, arch): - self.build_dir = self.get_build_dir(arch.arch) + def build(self, plat): + self.build_dir = self.get_build_dir(plat) if self.has_marker("building"): logger.warning("{} build for {} has been incomplete".format( - self.name, arch.arch)) + self.name, plat.arch)) logger.warning("Warning: deleting the build and restarting.") shutil.rmtree(self.build_dir, ignore_errors=True) - self.extract_arch(arch.arch) + self.extract_platform(plat) if self.has_marker("build_done"): - logger.info("Build python for {} already done.".format(arch.arch)) + logger.info("Build python for {} already done.".format(plat.arch)) return self.set_marker("building") chdir(self.build_dir) - logger.info("Prebuild {} for {}".format(self.name, arch.arch)) - self.prebuild_arch(arch) - logger.info("Build {} for {}".format(self.name, arch.arch)) - self.build_arch(arch) - logger.info("Postbuild {} for {}".format(self.name, arch.arch)) - self.postbuild_arch(arch) + logger.info("Prebuild {} for {}".format(self.name, plat.arch)) + self.prebuild_platform(plat) + logger.info("Build {} for {}".format(self.name, plat.arch)) + self.build_platform(plat) + logger.info("Postbuild {} for {}".format(self.name, plat.arch)) + self.postbuild_platform(plat) self.delete_marker("building") self.set_marker("build_done") @cache_execution def build_all(self): - filtered_archs = self.filtered_archs logger.info("Build {} for {} (filtered)".format( self.name, - ", ".join([x.arch for x in filtered_archs]))) - for arch in self.filtered_archs: - self.build(arch) + ", ".join([plat.name for plat in self.platforms_to_build]) + )) - name = self.name - if self.library: - logger.info("Create lipo library for {}".format(name)) - if not name.startswith("lib"): - name = "lib{}".format(name) - static_fn = join(self.ctx.dist_dir, "lib", "{}.a".format(name)) - ensure_dir(dirname(static_fn)) - logger.info("Lipo {} to {}".format(self.name, static_fn)) - self.make_lipo(static_fn) - if self.libraries: - logger.info("Create multiple lipo for {}".format(name)) - for library in self.libraries: - static_fn = join(self.ctx.dist_dir, "lib", basename(library)) - ensure_dir(dirname(static_fn)) - logger.info(" - Lipo-ize {}".format(library)) - self.make_lipo(static_fn, library) + for plat in self.platforms_to_build: + self.build(plat) + + logger.info(f"Create lipo libraries for {self.name}") + self.lipoize_libraries() + logger.info(f"Create xcframeworks for {self.name}") + self.create_xcframeworks() logger.info("Install include files for {}".format(self.name)) self.install_include() logger.info("Install frameworks for {}".format(self.name)) @@ -827,20 +864,20 @@ def build_all(self): logger.info("Install {}".format(self.name)) self.install() - def prebuild_arch(self, arch): - prebuild = "prebuild_{}".format(arch.arch) + def prebuild_platform(self, plat): + prebuild = "prebuild_{}".format(plat.arch) logger.debug("Invoking {}".format(prebuild)) if hasattr(self, prebuild): getattr(self, prebuild)() - def build_arch(self, arch): - build = "build_{}".format(arch.arch) + def build_platform(self, plat): + build = "build_{}".format(plat.arch) logger.debug("Invoking {}".format(build)) if hasattr(self, build): getattr(self, build)() - def postbuild_arch(self, arch): - postbuild = "postbuild_{}".format(arch.arch) + def postbuild_platform(self, plat): + postbuild = "postbuild_{}".format(plat.arch) logger.debug("Invoking {}".format(postbuild)) if hasattr(self, postbuild): getattr(self, postbuild)() @@ -858,26 +895,58 @@ def update_state(self, key, value): self.ctx.state[key_time] = now_str logger.debug("New State: {} at {}".format(key, now_str)) + def _get_all_libraries(self): + all_libraries = [] + if self.library: + all_libraries.append(self.library) + if self.libraries: + all_libraries.extend(self.libraries) + return all_libraries + @cache_execution - def make_lipo(self, filename, library=None): - if library is None: - library = self.library - if not library: - return - args = [] - for arch in self.filtered_archs: - library_fn = library.format(arch=arch) - args += [ - "-arch", arch.arch, - join(self.get_build_dir(arch.arch), library_fn)] - shprint(sh.lipo, "-create", "-output", filename, *args) + def lipoize_libraries(self): + + for library_fp in self._get_all_libraries(): + library_fn = basename(library_fp) + logger.info("Create lipo library for {}".format(library_fn)) + + # We are required to create a lipo library for each platform + # (iPhoneOS and iPhoneSimulator are 2 different platforms) + sdks_args = {} + for plat in self.platforms_to_build: + if plat.sdk not in sdks_args: + sdks_args[plat.sdk] = [] + sdks_args[plat.sdk].extend([ + "-arch", plat.arch, + join(self.get_build_dir(plat), library_fp.format(plat=plat)) + ]) + + for sdk, sdk_args in sdks_args.items(): + static_fn = join(self.ctx.dist_dir, "lib", sdk, library_fn) + ensure_dir(dirname(static_fn)) + shprint(sh.lipo, "-create", "-output", static_fn, *sdk_args) + + @cache_execution + def create_xcframeworks(self): + for library_fp in self._get_all_libraries(): + library_fn = basename(library_fp) + library_name = library_fn.split(".a")[0] + + xcframework_args = [] + for plat in self.platforms_to_build: + static_fn = join(self.ctx.dist_dir, "lib", plat.sdk, library_fn) + xcframework_args.extend(["-library", static_fn]) + + xcframework_fn = join(self.ctx.dist_dir, "xcframework", f"{library_name}.xcframework") + ensure_dir(dirname(xcframework_fn)) + shutil.rmtree(xcframework_fn, ignore_errors=True) + shprint(sh.xcodebuild, "-create-xcframework", *xcframework_args, "-output", xcframework_fn) @cache_execution def install_frameworks(self): if not self.frameworks: return - arch = self.filtered_archs[0] - build_dir = self.get_build_dir(arch.arch) + build_dir = self.get_build_dir(list(self.platforms_to_build)[0]) for framework in self.frameworks: logger.info("Install Framework {}".format(framework)) src = join(build_dir, framework) @@ -891,8 +960,7 @@ def install_frameworks(self): def install_sources(self): if not self.sources: return - arch = self.filtered_archs[0] - build_dir = self.get_build_dir(arch.arch) + build_dir = self.get_build_dir(list(self.platforms_to_build)[0]) for source in self.sources: logger.info("Install Sources{}".format(source)) src = join(build_dir, source) @@ -906,29 +974,25 @@ def install_sources(self): def install_include(self): if not self.include_dir: return - if self.include_per_arch: - archs = self.ctx.archs - else: - archs = self.filtered_archs[:1] include_dirs = self.include_dir if not isinstance(include_dirs, (list, tuple)): include_dirs = list([include_dirs]) - for arch in archs: - arch_dir = "common" - if self.include_per_arch: - arch_dir = arch.arch + for plat in self.platforms_to_build: + plat_dir = "common" + if self.include_per_platform: + plat_dir = plat.name include_name = self.include_name or self.name - dest_dir = join(self.ctx.include_dir, arch_dir, include_name) + dest_dir = join(self.ctx.include_dir, plat_dir, include_name) shutil.rmtree(dest_dir, ignore_errors=True) - build_dir = self.get_build_dir(arch.arch) + build_dir = self.get_build_dir(plat) for include_dir in include_dirs: dest_name = None if isinstance(include_dir, (list, tuple)): include_dir, dest_name = include_dir - include_dir = include_dir.format(arch=arch, ctx=self.ctx) + include_dir = include_dir.format(plat=plat, ctx=self.ctx) src_dir = join(build_dir, include_dir) if dest_name is None: dest_name = basename(src_dir) @@ -940,6 +1004,11 @@ def install_include(self): ensure_dir(dirname(dest)) shutil.copy(src_dir, dest) + if not self.include_per_platform: + # We only need to copy the include files once, even if we're + # building for multiple platforms. + break + @cache_execution def install_python_deps(self): for dep in self.python_depends: @@ -997,9 +1066,21 @@ def get_recipe(cls, name, ctx): class HostRecipe(Recipe): + @property - def archs(self): - return [platform.machine()] + def supported_platforms(self): + if platform.machine() == 'x86_64': + return ["macosx-x86_64"] + elif platform.machine() == 'arm64': + return ["macosx-arm64"] + + @property + def platforms_to_build(self): + for supported_platform in self.supported_platforms: + if supported_platform == "macosx-x86_64": + yield macOSx86_64Platform(self.ctx) + elif supported_platform == "macosx-arm64": + yield macOSARM64Platform(self.ctx) class PythonRecipe(Recipe): @@ -1013,15 +1094,16 @@ def install_python_package(self, name=None, env=None, is_dir=True): """Automate the installation of a Python package into the target site-packages. - It will works with the first filtered_archs, and the name of the recipe. + It will works with the first platforms_to_build, + and the name of the recipe. """ - arch = self.filtered_archs[0] + plat = list(self.platforms_to_build)[0] if name is None: name = self.name if env is None: - env = self.get_recipe_env(arch) + env = self.get_recipe_env(plat) logger.info("Install {} into the site-packages".format(name)) - build_dir = self.get_build_dir(arch.arch) + build_dir = self.get_build_dir(plat) chdir(build_dir) hostpython = sh.Command(self.ctx.hostpython) @@ -1072,18 +1154,19 @@ def biglink(self): cmd = sh.Command(join(self.ctx.root_dir, "tools", "biglink")) shprint(cmd, join(self.build_dir, "lib{}.a".format(self.name)), *dirs) - def get_recipe_env(self, arch): - env = super().get_recipe_env(arch) + def get_recipe_env(self, plat): + env = super().get_recipe_env(plat) env["KIVYIOSROOT"] = self.ctx.root_dir - env["IOSSDKROOT"] = arch.sysroot + env["IOSSDKROOT"] = plat.sysroot env["CUSTOMIZED_OSX_COMPILER"] = 'True' env["LDSHARED"] = join(self.ctx.root_dir, "tools", "liblink") env["ARM_LD"] = env["LD"] - env["ARCH"] = arch.arch + env["PLATFORM_SDK"] = plat.sdk + env["ARCH"] = plat.arch return env - def build_arch(self, arch): - build_env = self.get_recipe_env(arch) + def build_platform(self, plat): + build_env = self.get_recipe_env(plat) hostpython = sh.Command(self.ctx.hostpython) if self.pre_build_ext: with suppress(Exception): @@ -1208,7 +1291,7 @@ def update_pbxproj(filename, pbx_frameworks=None): if pbx_frameworks is None: pbx_frameworks = [] frameworks = [] - libraries = [] + xcframeworks = [] sources = [] for recipe in Recipe.list_recipes(): key = "{}.build_all".format(recipe) @@ -1218,21 +1301,21 @@ def update_pbxproj(filename, pbx_frameworks=None): recipe.init_with_ctx(ctx) pbx_frameworks.extend(recipe.pbx_frameworks) pbx_libraries.extend(recipe.pbx_libraries) - libraries.extend(recipe.dist_libraries) + xcframeworks.extend(recipe.dist_xcframeworks) frameworks.extend(recipe.frameworks) if recipe.sources: sources.append(recipe.name) pbx_frameworks = list(set(pbx_frameworks)) pbx_libraries = list(set(pbx_libraries)) - libraries = list(set(libraries)) + xcframeworks = list(set(xcframeworks)) logger.info("-" * 70) logger.info("The project need to have:") logger.info("iOS Frameworks: {}".format(pbx_frameworks)) logger.info("iOS Libraries: {}".format(pbx_libraries)) logger.info("iOS local Frameworks: {}".format(frameworks)) - logger.info("Libraries: {}".format(libraries)) + logger.info("XCFrameworks: {}".format(xcframeworks)) logger.info("Sources to link: {}".format(sources)) logger.info("-" * 70) @@ -1243,7 +1326,6 @@ def update_pbxproj(filename, pbx_frameworks=None): 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: @@ -1253,8 +1335,16 @@ def update_pbxproj(filename, pbx_frameworks=None): logger.info("Ensure {} is in the project (pbx_frameworks, system)".format(framework)) f_path = join(sysroot, "System", "Library", "Frameworks", "{}.framework".format(framework)) - project.add_file(f_path, parent=group, tree="DEVELOPER_DIR", - force=False, file_options=file_options) + project.add_file( + f_path, + parent=group, + tree="DEVELOPER_DIR", + force=False, + file_options=FileOptions( + embed_framework=False, + code_sign_on_copy=True + ), + ) for library in pbx_libraries: logger.info("Ensure {} is in the project (pbx_libraries, dylib+tbd)".format(library)) f_path = join(sysroot, "usr", "lib", @@ -1263,9 +1353,14 @@ def update_pbxproj(filename, pbx_frameworks=None): 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: - logger.info("Ensure {} is in the project (libraries)".format(library)) - project.add_file(library, parent=group, force=False) + for xcframework in xcframeworks: + logger.info("Ensure {} is in the project (xcframework)".format(xcframework)) + project.add_file( + xcframework, + parent=group, + force=False, + file_options=FileOptions(embed_framework=False) + ) for name in sources: logger.info("Ensure {} sources are used".format(name)) fn = join(ctx.dist_dir, "sources", name) @@ -1332,8 +1427,8 @@ def build(self): parser = argparse.ArgumentParser( description="Build the toolchain") parser.add_argument("recipe", nargs="+", help="Recipe to compile") - parser.add_argument("--arch", action="append", - help="Restrict compilation to this arch") + parser.add_argument("--platform", action="append", + help="Restrict compilation specific platform (multiple allowed)") parser.add_argument("--concurrency", type=int, default=ctx.num_cores, help="number of concurrent build processes (where supported)") parser.add_argument("--no-pigz", action="store_true", default=not bool(ctx.use_pigz), @@ -1344,19 +1439,26 @@ def build(self): help="Path to custom recipe") args = parser.parse_args(sys.argv[2:]) - if args.arch: - if len(args.arch) == 1: - archs = args.arch[0].split() - else: - archs = args.arch - available_archs = [arch.arch for arch in ctx.archs] - for arch in archs[:]: - if arch not in available_archs: - logger.error("Architecture {} invalid".format(arch)) - archs.remove(arch) - continue - ctx.archs = [arch for arch in ctx.archs if arch.arch in archs] - logger.info("Architectures restricted to: {}".format(archs)) + if args.platform: + + # User requested a specific set of platforms, so we need to reset + # the list of the selected platforms. + ctx.selected_platforms = [] + + for req_platform in args.platform: + + if req_platform in [plat.name for plat in ctx.selected_platforms]: + logger.error(f"Platform {req_platform} has been specified multiple times") + sys.exit(1) + + if req_platform not in [plat.name for plat in ctx.supported_platforms]: + logger.error(f"Platform {req_platform} is not supported") + sys.exit(1) + + ctx.selected_platforms.extend([plat for plat in ctx.supported_platforms if plat.name == req_platform]) + + logger.info(f"The following platforms has been requested to build: {ctx.selected_platforms}") + ctx.num_cores = args.concurrency if args.no_pigz: ctx.use_pigz = False @@ -1502,17 +1604,17 @@ def build_info(self): print("-------------") for attr in dir(ctx): if not attr.startswith("_"): - if not callable(attr) and attr != 'archs': + if not callable(attr) and attr != 'supported_platforms': print("{}: {}".format(attr, pformat(getattr(ctx, attr)))) - for arch in ctx.archs: - ul = '-' * (len(str(arch)) + 6) - print("\narch: {}\n{}".format(str(arch), ul)) - for attr in dir(arch): + for supported_platform in ctx.supported_platforms: + ul = '-' * (len(str(supported_platform)) + 6) + print("\narch: {}\n{}".format(str(supported_platform), ul)) + for attr in dir(supported_platform): if not attr.startswith("_"): if not callable(attr) and attr not in ['arch', 'ctx', 'get_env']: - print("{}: {}".format(attr, pformat(getattr(arch, attr)))) - env = arch.get_env() - print("env ({}): {}".format(arch, pformat(env))) + print("{}: {}".format(attr, pformat(getattr(supported_platform, attr)))) + env = supported_platform.get_env() + print("env ({}): {}".format(supported_platform, pformat(env))) def pip3(self): self.pip() diff --git a/kivy_ios/tools/liblink b/kivy_ios/tools/liblink index 957d2c02e..494266e8f 100755 --- a/kivy_ios/tools/liblink +++ b/kivy_ios/tools/liblink @@ -79,10 +79,13 @@ f.close() print('Liblink redirect linking with', objects) ld = environ.get('ARM_LD') arch = environ.get('ARCH', 'arm64') -if 'arm' in arch: +sdk = environ.get('PLATFORM_SDK', 'iphoneos') +if sdk == 'iphoneos': min_version_flag = '-ios_version_min' -else: +elif sdk == 'iphonesimulator': min_version_flag = '-ios_simulator_version_min' +else: + raise ValueError("Unsupported SDK: {}".format(sdk)) call = [ld, '-r', '-o', output + '.o', min_version_flag, '9.0', '-arch', arch] if min_version_flag == "-ios_version_min": call += ["-bitcode_bundle"] diff --git a/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/{{ cookiecutter.project_name }}.xcodeproj/project.pbxproj b/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/{{ cookiecutter.project_name }}.xcodeproj/project.pbxproj index 72fb8985e..026fad0f9 100755 --- a/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/{{ cookiecutter.project_name }}.xcodeproj/project.pbxproj +++ b/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/{{ cookiecutter.project_name }}.xcodeproj/project.pbxproj @@ -244,7 +244,6 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; EXCLUDED_ARCHS = ""; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = "{{ cookiecutter.dist_dir }}/frameworks"; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -262,7 +261,7 @@ "$(inherited)", "{{ cookiecutter.dist_dir }}/lib", ); - ONLY_ACTIVE_ARCH = NO; + ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-all_load"; PRODUCT_NAME = {{ cookiecutter.project_name }}; PROVISIONING_PROFILE = ""; @@ -284,7 +283,6 @@ CODE_SIGN_RESOURCE_RULES_PATH = "$(SDKROOT)/ResourceRules.plist"; COPY_PHASE_STRIP = NO; EXCLUDED_ARCHS = ""; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = "{{ cookiecutter.dist_dir }}/frameworks"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "";