summaryrefslogtreecommitdiff
path: root/recipes/moltenvk.recipe
blob: 8b7d0eacd9fd061425de098d49b673c19a3575f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# -*- 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 = []
            self.library_type = LibraryType.STATIC

        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.BOTH

    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()