| 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
 | import SCons.Util, os
import subprocess
import re
import shutil
def which(program_name):
    if hasattr(shutil, "which"):
        return shutil.which(program_name)
    else:
        path = os.getenv('PATH')
        for p in path.split(os.path.pathsep):
            p = os.path.join(p,program_name)
            if os.path.exists(p) and os.access(p,os.X_OK):
                return p
def generate(env) :
    def captureWinDeployQtMapping(release = True):
        p = False
        qt_bin_folder = ""
        if "QTDIR" in env:
            qt_bin_folder = env["QTDIR"] + "\\bin;"
        environ = {"PATH": qt_bin_folder + os.getenv("PATH"), "TEMP": os.getenv("TEMP"), "TMP": os.getenv("TMP")}
        if release:
            p = subprocess.Popen(['windeployqt', '--release', '--dry-run', '--list', 'mapping', 'Swift.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environ)
        else:
            p = subprocess.Popen(['windeployqt', '--debug', '--dry-run', '--list', 'mapping', 'Swift.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environ)
        if p:
            stdout, stderr = p.communicate()
            mappings = []
            p = re.compile(ur'"([^\"]*)" "([^\"]*)"')
            matches = re.findall(p, stdout)
            for match in matches:
                mappings.append(match)
            return mappings
        else:
            return False
    def createWindowsBundleManual(env, bundle, resources = {}, qtplugins = {}, qtlibs = [], qtversion = '4') :
        all_files = []
        all_files += env.Install(bundle, bundle + ".exe")
        for lib in qtlibs :
            all_files += env.Install(bundle, os.path.join(env["QTDIR"], "bin", lib + ".dll"))
        plugins_suffix = '4'
        if qtversion == '5' :
            plugins_suffix = ''
        for plugin_type in qtplugins:
            all_files += env.Install(os.path.join(bundle, plugin_type), [os.path.join(env["QTDIR"], "plugins", plugin_type, "q" + plugin + plugins_suffix + ".dll") for plugin in qtplugins[plugin_type]])
        for dir, resourceFiles in resources.items() :
            for resource in resourceFiles :
                e = env.Entry(resource)
                if e.isdir() :
                    for subresource in env.Glob(str(e) + "/*") :
                        all_files += env.Install(os.path.join(bundle, dir, e.name), subresource)
                else :
                    all_files += env.Install(os.path.join(bundle, dir), resource)
        return all_files
    # This version of uses windeployqt tool
    def createWindowsBundleWithWinDeployQt(env, bundle, resources = {}, qtplugins = {},  qtlibs = [],  qtversion = '4') :
        assert(qtversion == '5')
        all_files = []
        # add swift executable
        all_files += env.Install(bundle, bundle + ".exe")
        # adding resources (swift sounds/images/translations)
        for dir, resourceFiles in resources.items() :
            for resource in resourceFiles :
                e = env.Entry(resource)
                if e.isdir() :
                    for subresource in env.Glob(str(e) + "/*") :
                        all_files += env.Install(os.path.join(bundle, dir, e.name), subresource)
                else :
                    all_files += env.Install(os.path.join(bundle, dir), resource)
        qtmappings = captureWinDeployQtMapping()
        assert(qtmappings)
        # handle core DLLs
        qt_corelib_regex = re.compile(ur".*bin.*\\(.*)\.dll")
        for qtlib in qtlibs:
            if qtlib.startswith("Qt5"):
                (src_path, target_path) = next(((src_path, target_path) for (src_path, target_path) in qtmappings if  qt_corelib_regex.match(src_path) and qt_corelib_regex.match(src_path).group(1) == qtlib), (None, None))
                if src_path != None:
                    all_files += env.Install(bundle, src_path)
        # handle core dependencies
        for (src_path, target_path) in qtmappings:
            if qt_corelib_regex.match(src_path) and not qt_corelib_regex.match(src_path).group(1).startswith("Qt5"):
                all_files += env.Install(bundle, src_path)
        # handle plugins
        qt_plugin_regex = re.compile(ur".*plugins.*\\(.*)\\(.*)\.dll")
        for (src_path, target_path) in qtmappings:
            if qt_plugin_regex.match(src_path):
                plugin_folder, filename = qt_plugin_regex.match(src_path).groups()
                try:
                    if plugin_folder in ["audio"] or filename[1:] in qtplugins[plugin_folder]:
                        all_files += env.Install(os.path.join(bundle, plugin_folder), src_path)
                except:
                    pass
        return all_files
    def createWindowsBundle(env, bundle, resources = {}, qtplugins = {}, qtlibs = [], qtversion = '4'):
        if which("windeployqt.exe"):
            return createWindowsBundleWithWinDeployQt(env, bundle, resources, qtplugins, qtlibs, qtversion)
        else:
            return createWindowsBundleManual(env, bundle, resources, qtplugins, qtlibs, qtversion)
    env.AddMethod(createWindowsBundle, "WindowsBundle")
def exists(env) :
    return env["PLATFORM"] == "win32"
 |