# -*- Mode: Python -*- vi:si:et:sw=4:sts=4:ts=4:syntax=python import shutil from cerbero.utils import shell from cerbero.tools.libtool import LibtoolLibrary class Recipe(recipe.Recipe): name = 'moltenvk' version = '1.2.182.0' licenses = [License.Apachev2] stype = SourceType.CUSTOM btype = BuildType.CUSTOM files_bins = [ 'glslangValidator', 'glslc', 'spirv-as', 'spirv-cfg', 'spirv-cross', 'spirv-dis', 'spirv-link', 'spirv-opt', 'spirv-reduce', 'spirv-remap', 'spirv-val', 'vulkaninfo', ] files_libs = [ 'libMoltenVK' ] files_devel = [ 'include/vulkan', 'include/MoltenVK', ] def prepare(self): if self.config.target_platform not in (Platform.IOS, Platform.DARWIN): raise InvalidRecipeError(self, "Invalid platform") # no binaries available on iOS if self.config.target_platform == Platform.IOS: self.files_bins = [] if self.config.target_platform == Platform.DARWIN: # FIXME: libvulkan.dylib doesn't currently work with the # id/signature modifications we do later and may need to be rebuilt #self.files_libs += ['libvulkan'] # no libvulkan.a self.library_type = LibraryType.SHARED async def install(self): # only copy once for the architectures supported by the libraries if self.config.target_platform not in (Platform.IOS, Platform.DARWIN): return; if self.config.target_platform == Platform.IOS and self.config.target_arch != Architecture.ARM64: return; if self.config.target_platform == Platform.DARWIN \ and self.config.target_arch not in [Architecture.ARM64, Architecture.X86_64]: return srcdir = self.config.moltenvk_prefix prefix = self.config.prefix bindir = os.path.join(prefix, 'bin') libdir = os.path.join(prefix, 'lib') to_copy = [] for bin in self.files_bins: to_copy += [ (os.path.join(srcdir, 'macOS', 'bin', bin), os.path.join(bindir, bin), False) ] for d in ('vulkan', 'MoltenVK', 'vulkan-portability'): to_copy += [ (os.path.join(srcdir, 'MoltenVK', 'include', d), os.path.join(prefix, 'include', d), True) ] libmoltenvk_shared = os.path.join(libdir, 'libMoltenVK.dylib') libmoltenvk_static = os.path.join(libdir, 'libMoltenVK.a') libvulkan = os.path.join(libdir, 'libvulkan.dylib') libvulkan1 = os.path.join(libdir, 'libvulkan.1.dylib') if self.config.target_platform == Platform.DARWIN: to_copy += [ #(os.path.join(srcdir, 'macOS', 'lib', 'libvulkan.dylib'), # libvulkan, False), #(os.path.join(srcdir, 'macOS', 'lib', 'libvulkan.1.dylib'), # libvulkan1, False), (os.path.join(srcdir, 'MoltenVK', 'dylib', 'macOS', 'libMoltenVK.dylib'), libmoltenvk_shared, False), (os.path.join(srcdir, 'MoltenVK', 'MoltenVK.xcframework', 'macos-arm64_x86_64', 'libMoltenVK.a'), libmoltenvk_static, False) ] elif self.config.target_platform == Platform.IOS: to_copy += [ (os.path.join(srcdir, 'MoltenVK', 'dylib', 'iOS', 'libMoltenVK.dylib'), libmoltenvk_shared, False), (os.path.join(srcdir, 'MoltenVK', 'MoltenVK.xcframework', 'ios-arm64', 'libMoltenVK.a'), libmoltenvk_static, False) ] for src, dest, is_dir in to_copy: if is_dir: shell.copy_dir(src, dest) else: if not os.path.exists(os.path.dirname(dest)): os.makedirs(os.path.dirname(dest)) shutil.copy(src, dest) if self.config.target_platform == Platform.DARWIN: binaries = [os.path.join(bindir, x) for x in self.files_bins] for f in [libmoltenvk_shared]: # libvulkan, libvulkan1 # Because we are editing the binary, we need to the remove the signature. # The process would crash otherwise as not loadable await shell.async_call(['codesign', '--remove-signature', f], logfile=self.logfile) # we need to remove the @rpath from the libname await shell.async_call(['install_name_tool', '-id', f, f], logfile=self.logfile) # The SDK provides universal binaries, we need to convert them into thin binaries so # that the merge step can merge them back await shell.async_call(['lipo', '-thin', self.config.target_arch, f, '-output', f], logfile=self.logfile) # no need to change id for static libraries for f in binaries + [libmoltenvk_static]: # Because we are editing the binary, we need to the remove the signature. # The process would crash otherwise as not loadable await shell.async_call(['codesign', '--remove-signature', f], logfile=self.logfile) # The SDK provides universal binaries, we need to convert them into thin binaries so # that the merge step can merge them back await shell.async_call(['lipo', '-thin', self.config.target_arch, f, '-output', f], logfile=self.logfile) LibtoolLibrary('vulkan', None, None, None, libdir, self.config.target_platform).save() LibtoolLibrary('MoltenVK', None, None, None, libdir, self.config.target_platform).save()