diff --git a/kivy_ios/recipes/angle/__init__.py b/kivy_ios/recipes/angle/__init__.py new file mode 100644 index 00000000..29af2ef0 --- /dev/null +++ b/kivy_ios/recipes/angle/__init__.py @@ -0,0 +1,45 @@ +import os +import shutil + +from kivy_ios.toolchain import GenericPlatform, Recipe, cache_execution, logger + + +class IphoneAllUniversalPlatform(GenericPlatform): + + @property + def name(self): + return "iphoneall-universal" + + +class ANGLERecipe(Recipe): + version = "chromium-6367_rev1" + url = "https://github.com/kivy/angle-builder/releases/download/{version}/angle-iphoneall-universal.tar.gz" + include_dir = ["include"] + + @property + def platforms_to_build(self): + yield IphoneAllUniversalPlatform(self.ctx) + + @cache_execution + def build_all(self): + self.install_include() + self.install() + + @cache_execution + def install(self): + xcframework_folder = os.path.join(self.ctx.dist_dir, "xcframework") + + build_dir = self.get_build_dir( + plat=IphoneAllUniversalPlatform(self.ctx) + ) + + for fn in os.listdir(build_dir): + if fn.endswith(".xcframework"): + shutil.copytree( + os.path.join(build_dir, fn), + os.path.join(xcframework_folder, fn), + dirs_exist_ok=True + ) + + +recipe = ANGLERecipe() diff --git a/kivy_ios/recipes/hostpython3/__init__.py b/kivy_ios/recipes/hostpython3/__init__.py index 9ffa195f..8424be09 100644 --- a/kivy_ios/recipes/hostpython3/__init__.py +++ b/kivy_ios/recipes/hostpython3/__init__.py @@ -105,6 +105,17 @@ def install(self): "setuptools", ), ) + self.apply_patch( + "fix-ldshared-override.patch", + join( + self.ctx.dist_dir, + "hostpython3", + "lib", + "python3.11", + "site-packages", + "setuptools", + ), + ) recipe = Hostpython3Recipe() diff --git a/kivy_ios/recipes/hostpython3/fix-ldshared-override.patch b/kivy_ios/recipes/hostpython3/fix-ldshared-override.patch new file mode 100644 index 00000000..a2a7a145 --- /dev/null +++ b/kivy_ios/recipes/hostpython3/fix-ldshared-override.patch @@ -0,0 +1,31 @@ +diff -Naur setuptools.orig/_distutils/unixccompiler.py setuptools/_distutils/unixccompiler.py +--- setuptools.orig/_distutils/unixccompiler.py 2024-02-11 18:42:58 ++++ setuptools/_distutils/unixccompiler.py 2024-02-11 18:45:30 +@@ -253,14 +253,20 @@ + building_exe = target_desc == CCompiler.EXECUTABLE + linker = (self.linker_exe if building_exe else self.linker_so)[:] + +- if target_lang == "c++" and self.compiler_cxx: +- env, linker_ne = _split_env(linker) +- aix, linker_na = _split_aix(linker_ne) +- _, compiler_cxx_ne = _split_env(self.compiler_cxx) +- _, linker_exe_ne = _split_env(self.linker_exe) ++ # Mirko: We need our LDSHARED also for c++ things, ++ # otherwise our hack to have static libs does not work ++ # properly. ++ # We will likely remove all these caveats once PEP 730 ++ # is implemented (and we will conform to it). + +- params = _linker_params(linker_na, linker_exe_ne) +- linker = env + aix + compiler_cxx_ne + params ++ #if target_lang == "c++" and self.compiler_cxx: ++ # env, linker_ne = _split_env(linker) ++ # aix, linker_na = _split_aix(linker_ne) ++ # _, compiler_cxx_ne = _split_env(self.compiler_cxx) ++ # _, linker_exe_ne = _split_env(self.linker_exe) ++ ++ # params = _linker_params(linker_na, linker_exe_ne) ++ # linker = env + aix + compiler_cxx_ne + params + + linker = compiler_fixup(linker, ld_args) + diff --git a/kivy_ios/recipes/kivy/__init__.py b/kivy_ios/recipes/kivy/__init__.py index 0b314df0..7b01f9d5 100644 --- a/kivy_ios/recipes/kivy/__init__.py +++ b/kivy_ios/recipes/kivy/__init__.py @@ -7,13 +7,13 @@ class KivyRecipe(CythonRecipe): - version = "2.3.0" - url = "https://github.com/kivy/kivy/archive/{version}.zip" + version = "master" + url = "https://github.com/misl6/kivy/archive/refs/heads/feat/macos-angle-on-cametallayer.zip" library = "libkivy.a" - depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios", + depends = ["angle", "sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios", "pyobjus", "python"] - python_depends = ["certifi", "charset-normalizer", "idna", "requests", "urllib3"] - pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"] + python_depends = ["certifi", "charset-normalizer", "idna", "requests", "urllib3", "filetype"] + pbx_frameworks = ["Accelerate", "CoreMedia", "CoreVideo", "Metal"] pre_build_ext = True def get_recipe_env(self, plat): @@ -23,26 +23,10 @@ def get_recipe_env(self, plat): join(self.ctx.dist_dir, "include", "common", "sdl2_image"), join(self.ctx.dist_dir, "include", "common", "sdl2_ttf"), join(self.ctx.dist_dir, "include", "common", "sdl2_mixer")]) + env["KIVY_ANGLE_INCLUDE_DIR"] = join(self.ctx.dist_dir, "include", "common", "angle") + env["KIVY_ANGLE_LIB_DIR"] = join(self.ctx.dist_dir, "frameworks", plat.sdk) return env - def build_platform(self, plat): - self._patch_setup() - super().build_platform(plat) - - def _patch_setup(self): - # patch setup to remove some functionnalities - pyconfig = join(self.build_dir, "setup.py") - - def _remove_line(lines, pattern): - for line in lines[:]: - if pattern in line: - lines.remove(line) - with open(pyconfig) as fd: - lines = fd.readlines() - _remove_line(lines, "flags['libraries'] = ['GLESv2']") - with open(pyconfig, "w") as fd: - fd.writelines(lines) - def reduce_python_package(self): dest_dir = join(self.ctx.site_packages_dir, "kivy") shutil.rmtree(join(dest_dir, "tools")) diff --git a/kivy_ios/recipes/sdl2/__init__.py b/kivy_ios/recipes/sdl2/__init__.py index 3e34611d..627ffafd 100644 --- a/kivy_ios/recipes/sdl2/__init__.py +++ b/kivy_ios/recipes/sdl2/__init__.py @@ -8,13 +8,14 @@ class LibSDL2Recipe(Recipe): library = "Xcode/SDL/build/Release-{plat.sdk}/libSDL2.a" include_dir = "include" pbx_frameworks = [ - "OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics", + "AudioToolbox", "QuartzCore", "CoreGraphics", "CoreMotion", "GameController", "AVFoundation", "Metal", "UIKit", "CoreHaptics"] def prebuild_platform(self, plat): if self.has_marker("patched"): return + self.apply_patch("disable-opengl.patch") self.apply_patch("uikit-transparent.patch") self.apply_patch("disable-hidapi.patch") self.set_marker("patched") diff --git a/kivy_ios/recipes/sdl2/disable-opengl.patch b/kivy_ios/recipes/sdl2/disable-opengl.patch new file mode 100644 index 00000000..1c311df7 --- /dev/null +++ b/kivy_ios/recipes/sdl2/disable-opengl.patch @@ -0,0 +1,17 @@ +--- SDL2.orig/include/SDL_config_iphoneos.h 2024-02-11 14:06:54 ++++ SDL2/include/SDL_config_iphoneos.h 2024-02-11 14:07:22 +@@ -175,10 +175,10 @@ + + /* Enable OpenGL ES */ + #if !TARGET_OS_MACCATALYST +-#define SDL_VIDEO_OPENGL_ES2 1 +-#define SDL_VIDEO_OPENGL_ES 1 +-#define SDL_VIDEO_RENDER_OGL_ES 1 +-#define SDL_VIDEO_RENDER_OGL_ES2 1 ++#define SDL_VIDEO_OPENGL_ES2 0 ++#define SDL_VIDEO_OPENGL_ES 0 ++#define SDL_VIDEO_RENDER_OGL_ES 0 ++#define SDL_VIDEO_RENDER_OGL_ES2 0 + #endif + + /* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer diff --git a/kivy_ios/toolchain.py b/kivy_ios/toolchain.py index cd30b318..462821a8 100755 --- a/kivy_ios/toolchain.py +++ b/kivy_ios/toolchain.py @@ -250,6 +250,7 @@ def noicctempfile(): "-O3", self.version_min, ] + include_dirs) + env["CXXFLAGS"] = env["CFLAGS"] env["LDFLAGS"] = " ".join([ "-arch", self.arch, # "--sysroot", self.sysroot, diff --git a/kivy_ios/tools/cythonize.py b/kivy_ios/tools/cythonize.py index a1a011fc..4dcc8994 100755 --- a/kivy_ios/tools/cythonize.py +++ b/kivy_ios/tools/cythonize.py @@ -1,23 +1,17 @@ #!/usr/bin/env python3 -import os import sys -import subprocess -# resolve cython executable -cython = None - - -def resolve_cython(): - global cython - for executable in ('cython', 'cython-2.7'): - for path in os.environ['PATH'].split(':'): - if not os.path.exists(path): - continue - if executable in os.listdir(path): - cython = os.path.join(path, executable) - return +from Cython.Build.Cythonize import main as cythonize_main + +def is_cplus(fn): + # Check if there's the directive to compile as C++ + with open(fn) as fd: + for line in fd: + if line.startswith('# distutils: language = c++'): + return True + return False def do(fn): print('cythonize:', fn) @@ -29,13 +23,13 @@ def do(fn): package = '_'.join(parts[:-1]) # cythonize - subprocess.Popen([cython, fn], env=os.environ).communicate() + cythonize_main([fn]) if not package: print('no need to rewrite', fn) else: # get the .c, and change the initXXX - fn_c = fn[:-3] + 'c' + fn_c = fn[:-3] + ('c' if not is_cplus(fn) else 'cpp') with open(fn_c) as fd: data = fd.read() modname = modname.split('.')[-1] @@ -53,6 +47,9 @@ def do(fn): if __name__ == '__main__': print('-- cythonize', sys.argv) - resolve_cython() for fn in sys.argv[1:]: - do(fn) + try: + do(fn) + except: + print("Failed to cythonize, this is not necessarily a problem") + pass diff --git a/kivy_ios/tools/liblink b/kivy_ios/tools/liblink index c48a1456..d8a17061 100755 --- a/kivy_ios/tools/liblink +++ b/kivy_ios/tools/liblink @@ -23,6 +23,10 @@ while i < len(sys.argv): libs.append(opt) continue + if opt.startswith("-F"): + libs.append(opt) + continue + if opt in ("-r", "-pipe", "-no-cpp-precomp"): continue diff --git a/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/main.m b/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/main.m index 517eceb3..a900377d 100644 --- a/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/main.m +++ b/kivy_ios/tools/templates/{{ cookiecutter.project_name }}-ios/main.m @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { putenv("KIVY_WINDOW=sdl2"); putenv("KIVY_IMAGE=imageio,tex,gif,sdl2"); putenv("KIVY_AUDIO=sdl2"); - putenv("KIVY_GL_BACKEND=sdl2"); + putenv("KIVY_GL_BACKEND=angle"); // IOS_IS_WINDOWED=True disables fullscreen and then statusbar is shown putenv("IOS_IS_WINDOWED=False");