Skip to content

Commit 0f0e4e6

Browse files
committed
MetalANGLE support
1 parent 5da6cb8 commit 0f0e4e6

File tree

5 files changed

+112
-27
lines changed

5 files changed

+112
-27
lines changed

kivy_ios/recipes/kivy/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class KivyRecipe(CythonRecipe):
1919
depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
2020
"pyobjus", "python", "host_setuptools3"]
2121
python_depends = ["certifi"]
22-
pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"]
22+
pbx_frameworks = ["Accelerate", "CoreMedia", "CoreVideo"]
2323
pre_build_ext = True
2424

2525
def get_recipe_env(self, arch):
@@ -43,9 +43,17 @@ def _remove_line(lines, pattern):
4343
for line in lines[:]:
4444
if pattern in line:
4545
lines.remove(line)
46+
47+
def _sub_pattern(lines, pattern_old, pattern_new):
48+
for i, line in enumerate(lines[:]):
49+
if pattern_old in line:
50+
lines[i] = lines[i].replace(pattern_old, pattern_new)
51+
4652
with open(pyconfig) as fd:
4753
lines = fd.readlines()
4854
_remove_line(lines, "flags['libraries'] = ['GLESv2']")
55+
_sub_pattern(lines, "OpenGLES", "MetalANGLE")
56+
# _remove_line(lines, "c_options['use_sdl'] = True")
4957
with open(pyconfig, "w") as fd:
5058
fd.writelines(lines)
5159

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from kivy_ios.toolchain import Recipe, shprint
2+
from os.path import join
3+
import sh
4+
5+
6+
class MetalAngleFramework(Recipe):
7+
version = "master"
8+
url = "https://github.com/kakashidinho/metalangle/archive/{version}.zip"
9+
frameworks = [dict(name="MetalANGLE", path="ios/xcode/build/Release-{arch.sdk}/MetalANGLE.framework")]
10+
11+
def prebuild_arch(self, arch):
12+
if self.has_marker("thirdparty_downloaded"):
13+
return
14+
shprint(sh.sh, join(self.build_dir, "ios", "xcode", "fetchDependencies.sh"))
15+
self.set_marker("thirdparty_downloaded")
16+
17+
def build_arch(self, arch):
18+
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild,
19+
"ONLY_ACTIVE_ARCH=NO",
20+
"ARCHS={}".format(arch.arch),
21+
"-sdk", arch.sdk,
22+
"-project", "ios/xcode/OpenGLES.xcodeproj",
23+
"-target", "MetalANGLE",
24+
"-configuration", "Release")
25+
26+
27+
recipe = MetalAngleFramework()

kivy_ios/recipes/sdl2/__init__.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
from kivy_ios.toolchain import Recipe, shprint
22
import sh
3+
from os.path import join
34

45

56
class LibSDL2Recipe(Recipe):
67
# version = "2.0.9"
78
# url = "https://www.libsdl.org/release/SDL2-{version}.tar.gz"
8-
version = "7cc4fc886d9e"
9-
url = "https://hg.libsdl.org/SDL/archive/{version}.tar.gz"
9+
version = "metalangle"
10+
url = "https://github.com/misl6/SDL-mirror/archive/{version}.zip"
1011
library = "Xcode-iOS/SDL/build/Release-{arch.sdk}/libSDL2.a"
1112
include_dir = "include"
12-
pbx_frameworks = [
13-
"OpenGLES", "AudioToolbox", "QuartzCore", "CoreGraphics",
14-
"CoreMotion", "GameController", "AVFoundation", "Metal",
15-
"UIKit"]
13+
depends = ["metalangle"]
14+
pbx_frameworks = ["AudioToolbox", "QuartzCore", "CoreGraphics", "CoreMotion",
15+
"GameController", "AVFoundation", "Metal", "UIKit", "MetalANGLE"]
1616

1717
def prebuild_arch(self, arch):
1818
if self.has_marker("patched"):
1919
return
20-
self.apply_patch("uikit-transparent.patch")
20+
# self.apply_patch("uikit-transparent.patch")
21+
22+
def _sub_pattern(lines, pattern_old, pattern_new):
23+
for i, line in enumerate(lines[:]):
24+
if pattern_old in line:
25+
lines[i] = lines[i].replace(pattern_old, pattern_new)
26+
sdl2pbxproj = join(self.build_dir, "Xcode-iOS", "SDL", "SDL.xcodeproj", "project.pbxproj")
27+
with open(sdl2pbxproj) as fd:
28+
lines = fd.readlines()
29+
_sub_pattern(lines, "--YOURFRAMEMETALANGLEWORKPATH--", join(self.ctx.dist_dir, 'frameworks'))
30+
with open(sdl2pbxproj, "w") as fd:
31+
fd.writelines(lines)
2132
self.set_marker("patched")
2233

2334
def build_arch(self, arch):

kivy_ios/toolchain.py

+31-19
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,13 @@ def build_all(self):
811811
self.make_lipo(static_fn, library)
812812
logger.info("Install include files for {}".format(self.name))
813813
self.install_include()
814-
logger.info("Install frameworks for {}".format(self.name))
815-
self.install_frameworks()
814+
if self.frameworks:
815+
logger.info("Make lipo framework for {}".format(self.name))
816+
for framework in self.frameworks:
817+
framework_fn = join(self.ctx.dist_dir, "frameworks", "{}.framework".format(framework['name']))
818+
ensure_dir(dirname(framework_fn))
819+
logger.info(" - Lipo-ize {}".format(framework['name']))
820+
self.make_lipo_framework(framework_fn, framework)
816821
logger.info("Install sources for {}".format(self.name))
817822
self.install_sources()
818823
logger.info("Install python deps for {}".format(self.name))
@@ -865,19 +870,24 @@ def make_lipo(self, filename, library=None):
865870
shprint(sh.lipo, "-create", "-output", filename, *args)
866871

867872
@cache_execution
868-
def install_frameworks(self):
869-
if not self.frameworks:
873+
def make_lipo_framework(self, filename, framework=None):
874+
if framework is None:
875+
framework = self.framework
876+
if not framework:
870877
return
871-
arch = self.filtered_archs[0]
872-
build_dir = self.get_build_dir(arch.arch)
873-
for framework in self.frameworks:
874-
logger.info("Install Framework {}".format(framework))
875-
src = join(build_dir, framework)
876-
dest = join(self.ctx.dist_dir, "frameworks", framework)
877-
ensure_dir(dirname(dest))
878-
shutil.rmtree(dest, ignore_errors=True)
879-
logger.debug("Copy {} to {}".format(src, dest))
880-
shutil.copytree(src, dest)
878+
args = []
879+
ensure_dir(filename)
880+
for arch in self.filtered_archs:
881+
framework_p = framework['path'].format(arch=arch)
882+
args += [join(self.get_build_dir(arch.arch), framework_p, framework['name'])]
883+
logger.info("Copy the framework folder for Headers, Info.plst, etc in place")
884+
shprint(sh.cp, "-r",
885+
join(self.get_build_dir(self.filtered_archs[0].arch),
886+
framework['path'].format(arch=self.filtered_archs[0])),
887+
join(self.ctx.dist_dir, "frameworks"))
888+
shprint(sh.rm, join(filename, framework['name']))
889+
logger.info("Lipo-ize the framework")
890+
shprint(sh.lipo, "-create", "-output", join(filename, framework['name']), *args)
881891

882892
@cache_execution
883893
def install_sources(self):
@@ -1208,17 +1218,19 @@ def update_pbxproj(filename, pbx_frameworks=None):
12081218
group = project.get_or_create_group("Frameworks")
12091219
g_classes = project.get_or_create_group("Classes")
12101220
file_options = FileOptions(embed_framework=False, code_sign_on_copy=True)
1221+
file_options_embed = FileOptions(embed_framework=True, code_sign_on_copy=True)
12111222
for framework in pbx_frameworks:
1212-
framework_name = "{}.framework".format(framework)
1213-
if framework_name in frameworks:
1223+
if framework in [x['name'] for x in frameworks]:
12141224
logger.info("Ensure {} is in the project (pbx_frameworks, local)".format(framework))
1215-
f_path = join(ctx.dist_dir, "frameworks", framework_name)
1225+
f_path = join(ctx.dist_dir, "frameworks", f"{framework}.framework")
1226+
project.add_file(f_path, parent=group, tree="DEVELOPER_DIR",
1227+
force=False, file_options=file_options_embed)
12161228
else:
12171229
logger.info("Ensure {} is in the project (pbx_frameworks, system)".format(framework))
12181230
f_path = join(sysroot, "System", "Library", "Frameworks",
12191231
"{}.framework".format(framework))
1220-
project.add_file(f_path, parent=group, tree="DEVELOPER_DIR",
1221-
force=False, file_options=file_options)
1232+
project.add_file(f_path, parent=group, tree="DEVELOPER_DIR",
1233+
force=False, file_options=file_options)
12221234
for library in pbx_libraries:
12231235
logger.info("Ensure {} is in the project (pbx_libraries, dylib+tbd)".format(library))
12241236
f_path = join(sysroot, "usr", "lib",

recipes/metalangle/__init__.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from toolchain import Recipe, shprint
2+
from os.path import join
3+
import sh
4+
5+
6+
class MetalAngleFramework(Recipe):
7+
version = "master"
8+
url = "https://github.com/kakashidinho/metalangle/archive/{version}.zip"
9+
frameworks = [dict(name="MetalANGLE", path="ios/xcode/build/Release-{arch.sdk}/MetalANGLE.framework")]
10+
11+
def prebuild_arch(self, arch):
12+
if self.has_marker("thirdparty_downloaded"):
13+
return
14+
shprint(sh.sh, join(self.build_dir, "ios", "xcode", "fetchDependencies.sh"))
15+
self.set_marker("thirdparty_downloaded")
16+
17+
def build_arch(self, arch):
18+
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild,
19+
"ONLY_ACTIVE_ARCH=NO",
20+
"ARCHS={}".format(arch.arch),
21+
"-sdk", arch.sdk,
22+
"-project", "ios/xcode/OpenGLES.xcodeproj",
23+
"-target", "MetalANGLE",
24+
"-configuration", "Release")
25+
26+
27+
recipe = MetalAngleFramework()

0 commit comments

Comments
 (0)