Skip to content

Commit

Permalink
MetalANGLE support
Browse files Browse the repository at this point in the history
  • Loading branch information
misl6 committed May 9, 2020
1 parent 5da6cb8 commit 0f0e4e6
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 27 deletions.
10 changes: 9 additions & 1 deletion kivy_ios/recipes/kivy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class KivyRecipe(CythonRecipe):
depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
"pyobjus", "python", "host_setuptools3"]
python_depends = ["certifi"]
pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"]
pbx_frameworks = ["Accelerate", "CoreMedia", "CoreVideo"]
pre_build_ext = True

def get_recipe_env(self, arch):
Expand All @@ -43,9 +43,17 @@ def _remove_line(lines, pattern):
for line in lines[:]:
if pattern in line:
lines.remove(line)

def _sub_pattern(lines, pattern_old, pattern_new):
for i, line in enumerate(lines[:]):
if pattern_old in line:
lines[i] = lines[i].replace(pattern_old, pattern_new)

with open(pyconfig) as fd:
lines = fd.readlines()
_remove_line(lines, "flags['libraries'] = ['GLESv2']")
_sub_pattern(lines, "OpenGLES", "MetalANGLE")
# _remove_line(lines, "c_options['use_sdl'] = True")
with open(pyconfig, "w") as fd:
fd.writelines(lines)

Expand Down
27 changes: 27 additions & 0 deletions kivy_ios/recipes/metalangle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from kivy_ios.toolchain import Recipe, shprint
from os.path import join
import sh


class MetalAngleFramework(Recipe):
version = "master"
url = "https://github.com/kakashidinho/metalangle/archive/{version}.zip"
frameworks = [dict(name="MetalANGLE", path="ios/xcode/build/Release-{arch.sdk}/MetalANGLE.framework")]

def prebuild_arch(self, arch):
if self.has_marker("thirdparty_downloaded"):
return
shprint(sh.sh, join(self.build_dir, "ios", "xcode", "fetchDependencies.sh"))
self.set_marker("thirdparty_downloaded")

def build_arch(self, arch):
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild,
"ONLY_ACTIVE_ARCH=NO",
"ARCHS={}".format(arch.arch),
"-sdk", arch.sdk,
"-project", "ios/xcode/OpenGLES.xcodeproj",
"-target", "MetalANGLE",
"-configuration", "Release")


recipe = MetalAngleFramework()
25 changes: 18 additions & 7 deletions kivy_ios/recipes/sdl2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
from kivy_ios.toolchain import Recipe, shprint
import sh
from os.path import join


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

def prebuild_arch(self, arch):
if self.has_marker("patched"):
return
self.apply_patch("uikit-transparent.patch")
# self.apply_patch("uikit-transparent.patch")

def _sub_pattern(lines, pattern_old, pattern_new):
for i, line in enumerate(lines[:]):
if pattern_old in line:
lines[i] = lines[i].replace(pattern_old, pattern_new)
sdl2pbxproj = join(self.build_dir, "Xcode-iOS", "SDL", "SDL.xcodeproj", "project.pbxproj")
with open(sdl2pbxproj) as fd:
lines = fd.readlines()
_sub_pattern(lines, "--YOURFRAMEMETALANGLEWORKPATH--", join(self.ctx.dist_dir, 'frameworks'))
with open(sdl2pbxproj, "w") as fd:
fd.writelines(lines)
self.set_marker("patched")

def build_arch(self, arch):
Expand Down
50 changes: 31 additions & 19 deletions kivy_ios/toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -811,8 +811,13 @@ def build_all(self):
self.make_lipo(static_fn, library)
logger.info("Install include files for {}".format(self.name))
self.install_include()
logger.info("Install frameworks for {}".format(self.name))
self.install_frameworks()
if self.frameworks:
logger.info("Make lipo framework for {}".format(self.name))
for framework in self.frameworks:
framework_fn = join(self.ctx.dist_dir, "frameworks", "{}.framework".format(framework['name']))
ensure_dir(dirname(framework_fn))
logger.info(" - Lipo-ize {}".format(framework['name']))
self.make_lipo_framework(framework_fn, framework)
logger.info("Install sources for {}".format(self.name))
self.install_sources()
logger.info("Install python deps for {}".format(self.name))
Expand Down Expand Up @@ -865,19 +870,24 @@ def make_lipo(self, filename, library=None):
shprint(sh.lipo, "-create", "-output", filename, *args)

@cache_execution
def install_frameworks(self):
if not self.frameworks:
def make_lipo_framework(self, filename, framework=None):
if framework is None:
framework = self.framework
if not framework:
return
arch = self.filtered_archs[0]
build_dir = self.get_build_dir(arch.arch)
for framework in self.frameworks:
logger.info("Install Framework {}".format(framework))
src = join(build_dir, framework)
dest = join(self.ctx.dist_dir, "frameworks", framework)
ensure_dir(dirname(dest))
shutil.rmtree(dest, ignore_errors=True)
logger.debug("Copy {} to {}".format(src, dest))
shutil.copytree(src, dest)
args = []
ensure_dir(filename)
for arch in self.filtered_archs:
framework_p = framework['path'].format(arch=arch)
args += [join(self.get_build_dir(arch.arch), framework_p, framework['name'])]
logger.info("Copy the framework folder for Headers, Info.plst, etc in place")
shprint(sh.cp, "-r",
join(self.get_build_dir(self.filtered_archs[0].arch),
framework['path'].format(arch=self.filtered_archs[0])),
join(self.ctx.dist_dir, "frameworks"))
shprint(sh.rm, join(filename, framework['name']))
logger.info("Lipo-ize the framework")
shprint(sh.lipo, "-create", "-output", join(filename, framework['name']), *args)

@cache_execution
def install_sources(self):
Expand Down Expand Up @@ -1208,17 +1218,19 @@ 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)
file_options_embed = FileOptions(embed_framework=True, code_sign_on_copy=True)
for framework in pbx_frameworks:
framework_name = "{}.framework".format(framework)
if framework_name in frameworks:
if framework in [x['name'] for x in frameworks]:
logger.info("Ensure {} is in the project (pbx_frameworks, local)".format(framework))
f_path = join(ctx.dist_dir, "frameworks", framework_name)
f_path = join(ctx.dist_dir, "frameworks", f"{framework}.framework")
project.add_file(f_path, parent=group, tree="DEVELOPER_DIR",
force=False, file_options=file_options_embed)
else:
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=file_options)
for library in pbx_libraries:
logger.info("Ensure {} is in the project (pbx_libraries, dylib+tbd)".format(library))
f_path = join(sysroot, "usr", "lib",
Expand Down
27 changes: 27 additions & 0 deletions recipes/metalangle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from toolchain import Recipe, shprint
from os.path import join
import sh


class MetalAngleFramework(Recipe):
version = "master"
url = "https://github.com/kakashidinho/metalangle/archive/{version}.zip"
frameworks = [dict(name="MetalANGLE", path="ios/xcode/build/Release-{arch.sdk}/MetalANGLE.framework")]

def prebuild_arch(self, arch):
if self.has_marker("thirdparty_downloaded"):
return
shprint(sh.sh, join(self.build_dir, "ios", "xcode", "fetchDependencies.sh"))
self.set_marker("thirdparty_downloaded")

def build_arch(self, arch):
shprint(sh.xcodebuild, self.ctx.concurrent_xcodebuild,
"ONLY_ACTIVE_ARCH=NO",
"ARCHS={}".format(arch.arch),
"-sdk", arch.sdk,
"-project", "ios/xcode/OpenGLES.xcodeproj",
"-target", "MetalANGLE",
"-configuration", "Release")


recipe = MetalAngleFramework()

0 comments on commit 0f0e4e6

Please sign in to comment.