diff options
author | Tobias Markmann <tm@ayena.de> | 2015-02-05 10:18:47 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2015-02-06 13:38:42 (GMT) |
commit | 9f6d02730918faa041afc39ec51b57675b4c5c1d (patch) | |
tree | 69292bfe21abe04541e0f6eccc31d59fc97763fd | |
parent | 8421b895f5697ebf680c124f84a68dcdea029c62 (diff) | |
download | swift-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
-rw-r--r-- | BuildTools/SCons/Tools/WindowsBundle.py | 100 | ||||
-rw-r--r-- | Documentation/BuildingOnWindows.txt | 5 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 32 |
3 files changed, 111 insertions, 26 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) : diff --git a/Documentation/BuildingOnWindows.txt b/Documentation/BuildingOnWindows.txt index a2d9948..c411d62 100644 --- a/Documentation/BuildingOnWindows.txt +++ b/Documentation/BuildingOnWindows.txt @@ -42,12 +42,13 @@ Running tests Packaging Swift --------------- For packaging use: -- Microsoft Visual C++ Express 2008 +- Microsoft Visual C++ Express 2008 or Microsoft VS 2013 Express - No OpenSSL - WiX +- Download the C++ redistributable package from Microsoft and put it at C:\Program Files (x86)\Common Files\Merge Modules\ - config.py should contain: qt = "c:\\qt\\4.7.4" - vcredist = "c:\\Program Files\\Common Files\\Merge Modules" + vcredist = "C:\\Program Files (x86)\\Common Files\\Merge Modules\\vcredist_x86.exe" debug = 1 optimize = 1 wix_bindir = "c:\\program files\\Windows Installer XML v3.5\\bin" diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 6e90cd4..858df19 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -1,4 +1,4 @@ -import os, shutil, datetime, re, time +import os, datetime, re, time import Version def generateDefaultTheme(dir) : @@ -358,7 +358,7 @@ if env["PLATFORM"] == "darwin" : myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dmg"], [app], ["Swift/Packaging/MacOSX/package.sh " + app.path + " Swift/Packaging/MacOSX/Swift.dmg.gz $TARGET $QTDIR"]) dsym = myenv.Command(["Swift-${SWIFT_VERSION}.dSYM"], ["Swift"], ["dsymutil -o ${TARGET} ${SOURCE}"]) myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dSYM.zip"], dsym, ["cd ${SOURCE.dir} && zip -r ${TARGET.abspath} ${SOURCE.name}"]) - + if env.get("SWIFT_INSTALLDIR", "") : env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "bin"), swiftProgram + openURIProgram) env.InstallAs(os.path.join(env["SWIFT_INSTALLDIR"], "share", "pixmaps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm") @@ -368,15 +368,15 @@ if env.get("SWIFT_INSTALLDIR", "") : for i in ["16", "22", "24", "64", "128"] : env.InstallAs(os.path.join(icons_path, i + "x" + i, "apps", "swift.png"), "#/Swift/resources/logo/logo-icon-" + i + ".png") env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "applications"), "#/Swift/resources/swift.desktop") - for dir, resource in commonResources.items() : + for dir, resource in commonResources.items() : env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "swift", dir), resource) - + if env["PLATFORM"] == "win32" : if env["DIST"] or ARGUMENTS.get("dump_trace") : commonResources[""] = commonResources.get("", []) + [ - #os.path.join(env["OPENSSL_DIR"], "bin", "ssleay32.dll"), + #os.path.join(env["OPENSSL_DIR"], "bin", "ssleay32.dll"), #os.path.join(env["OPENSSL_DIR"], "bin", "libeay32.dll"), - "#/Swift/resources/images", + "#/Swift/resources/images", ] if env["SWIFTEN_DLL"] : commonResources[""] = commonResources.get("", []) + ["#/Swiften/${SWIFTEN_LIBRARY_FILE}"] @@ -392,11 +392,12 @@ if env["PLATFORM"] == "win32" : qtlibs += ['icuin51', 'icuuc51', 'icudt51', 'libGLESv2', 'libEGL'] qtplugins["platforms"] = ['windows'] qtplugins["accessible"] = ["taccessiblewidgets"] - windowsBundleFiles = myenv.WindowsBundle("Swift", - resources = commonResources, - qtplugins = qtplugins, - qtlibs = qtlibs, - qtversion = qt_version) + + windowsBundleFiles = myenv.WindowsBundle("Swift", + resources = commonResources, + qtplugins = qtplugins, + qtlibs = qtlibs, + qtversion = qt_version) if env["DIST"] : #myenv.Append(NSIS_OPTIONS = [ @@ -415,7 +416,7 @@ if env["PLATFORM"] == "win32" : # FIXME: This is incorrect, because it only works for latin1. # The correct way is \u<decimal utf16 point>? , but this is more # work - outfile.write("\\'%X" % ord(char)) + outfile.write("\\'%X" % ord(char)) else : outfile.write(char) outfile.write('\\par ') @@ -423,10 +424,9 @@ if env["PLATFORM"] == "win32" : outfile.close() infile.close() copying = env.Command(["Swift/COPYING.rtf"], ["COPYING"], convertToRTF) - wixvariables = { 'VCCRTFile': env["vcredist"], - 'Version': str(myenv["SWIFT_VERSION_MAJOR"]) + "." + str(myenv["SWIFT_VERSION_MINOR"]) + "." + str(myenv["SWIFT_VERSION_PATCH"]) + 'Version': str(myenv["SWIFT_VERSION_MAJOR"]) + "." + str(myenv["SWIFT_VERSION_MINOR"]) + "." + str(myenv["SWIFT_VERSION_PATCH"]) } wixincludecontent = "<Include>" for key in wixvariables: @@ -438,8 +438,6 @@ if env["PLATFORM"] == "win32" : myenv.WiX_Candle('..\\Packaging\\WiX\\Swift.wixobj', '..\\Packaging\\WiX\\Swift.wxs') myenv.WiX_Candle('..\\Packaging\\WiX\\gen_files.wixobj', '..\\Packaging\\WiX\\gen_files.wxs') myenv.WiX_Light('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.msi', ['..\\Packaging\\WiX\\gen_files.wixobj','..\\Packaging\\WiX\\Swift.wixobj']) - + if myenv["debug"] : myenv.InstallAs('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.pdb', "Swift.pdb") - - |