summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2015-02-05 10:18:47 (GMT)
committerSwift Review <review@swift.im>2015-02-06 13:38:42 (GMT)
commit9f6d02730918faa041afc39ec51b57675b4c5c1d (patch)
tree69292bfe21abe04541e0f6eccc31d59fc97763fd /BuildTools/SCons/Tools
parent8421b895f5697ebf680c124f84a68dcdea029c62 (diff)
downloadswift-9f6d02730918faa041afc39ec51b57675b4c5c1d.zip
swift-9f6d02730918faa041afc39ec51b57675b4c5c1d.tar.bz2
Use windeployqt.exe if available and Win distribution documentation fix
If windeployqt.exe is available for Qt5, it will be used to detect which Qt DLLs to put in the Windows distribution and its dependencies correctly. Added a note to our Windows building documentation about the VS redistributable. Test-Information: Tested building a MSI package on Windows 8.1 Pro with Qt 5.3.2 32-bit msvc2013_opengl which successfully installs and runs. Change-Id: I786da40d6467f1de8e64bfae275f8363ac1d5ba8
Diffstat (limited to 'BuildTools/SCons/Tools')
-rw-r--r--BuildTools/SCons/Tools/WindowsBundle.py100
1 files changed, 93 insertions, 7 deletions
diff --git a/BuildTools/SCons/Tools/WindowsBundle.py b/BuildTools/SCons/Tools/WindowsBundle.py
index 2915141..33ace7f 100644
--- a/BuildTools/SCons/Tools/WindowsBundle.py
+++ b/BuildTools/SCons/Tools/WindowsBundle.py
@@ -1,7 +1,41 @@
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 createWindowsBundle(env, bundle, resources = {}, qtplugins = {}, qtlibs = [], qtversion = '4') :
+ def captureWinDeployQtMapping(release = True):
+ p = False
+ if release:
+ p = subprocess.Popen(['windeployqt', '--release', '--dry-run', '--list', 'mapping', 'Swift.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ else:
+ p = subprocess.Popen(['windeployqt', '--debug', '--dry-run', '--list', 'mapping', 'Swift.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ 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 :
@@ -11,17 +45,69 @@ def generate(env) :
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)
+ 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:
+ 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"):
+ 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 filename[1:] in qtplugins[plugin_folder]:
+ 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) :