X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=scripts%2Fbuild%2Fmacosx_DeployApp.py;h=e6cfc1d189ac29f4acc49fbf8133789fb40c81b2;hp=a7aae571baec7e127c97420b923684cf6b60fb48;hb=f89390a2e9ba9a4a64f3a545c147c046fbe07a16;hpb=713f393f8890be442e3e8485b178f7b931b4948c diff --git a/scripts/build/macosx_DeployApp.py b/scripts/build/macosx_DeployApp.py index a7aae571..e6cfc1d1 100755 --- a/scripts/build/macosx_DeployApp.py +++ b/scripts/build/macosx_DeployApp.py @@ -15,22 +15,33 @@ # ============================== import sys import os +import os.path from subprocess import Popen, PIPE +# ============================== +# Constants +# ============================== +QT_CONFIG = """[Paths] + Plugins = plugins +""" + +QT_CONFIG_NOBUNDLE = """[Paths] + Prefix = ../ + Plugins = plugins +""" + + class InstallQt(object): - def __init__(self, appdir, bundle = True): + def __init__(self, appdir, bundle=True, requestedPlugins=[]): self.appDir = appdir self.bundle = bundle + self.frameworkDir = self.appDir + "/Frameworks" + self.pluginDir = self.appDir + "/plugins" self.executableDir = self.appDir if bundle: self.executableDir += "/MacOS" - if bundle: - self.frameworkDir = self.appDir + "/Frameworks" - else: - self.frameworkDir = self.executableDir + "/Frameworks" - self.installedFrameworks = set() self.findFrameworkPath() @@ -39,17 +50,101 @@ class InstallQt(object): for executable in executables: self.resolveDependancies(executable) + self.findPluginsPath() + self.installPlugins(requestedPlugins) + self.installQtConf() + + def qtProperty(self, qtProperty): + """ + Query persistent property of Qt via qmake + """ + VALID_PROPERTIES = ['QT_INSTALL_PREFIX', + 'QT_INSTALL_DATA', + 'QT_INSTALL_DOCS', + 'QT_INSTALL_HEADERS', + 'QT_INSTALL_LIBS', + 'QT_INSTALL_BINS', + 'QT_INSTALL_PLUGINS', + 'QT_INSTALL_IMPORTS', + 'QT_INSTALL_TRANSLATIONS', + 'QT_INSTALL_CONFIGURATION', + 'QT_INSTALL_EXAMPLES', + 'QT_INSTALL_DEMOS', + 'QMAKE_MKSPECS', + 'QMAKE_VERSION', + 'QT_VERSION' + ] + if qtProperty not in VALID_PROPERTIES: + return None + + qmakeProcess = Popen('qmake -query %s' % qtProperty, shell=True, stdout=PIPE, stderr=PIPE) + result = qmakeProcess.stdout.read().strip() + qmakeProcess.stdout.close() + qmakeProcess.wait() + return result + def findFrameworkPath(self): - qmakeProcess = Popen('qmake -query QT_INSTALL_LIBS', shell=True, stdout=PIPE, stderr=PIPE) - self.sourceFrameworkPath = qmakeProcess.stdout.read().strip() + self.sourceFrameworkPath = self.qtProperty('QT_INSTALL_LIBS') + + def findPluginsPath(self): + self.sourcePluginsPath = self.qtProperty('QT_INSTALL_PLUGINS') + + def findPlugin(self, pluginname): + qmakeProcess = Popen('find %s -name %s' % (self.sourcePluginsPath, pluginname), shell=True, stdout=PIPE, stderr=PIPE) + result = qmakeProcess.stdout.read().strip() qmakeProcess.stdout.close() qmakeProcess.wait() + if not result: + raise OSError + return result + + def installPlugins(self, requestedPlugins): + try: + os.mkdir(self.pluginDir) + except: + pass + + for plugin in requestedPlugins: + if not plugin.isalnum(): + print "Skipping library '%s'..." % plugin + continue + + pluginName = "lib%s.dylib" % plugin + pluginSource = '' + try: + pluginSource = self.findPlugin(pluginName) + except OSError: + print "WARNING: Requested library does not exist: '%s'" % plugin + continue + + pluginSubDir = os.path.dirname(pluginSource) + pluginSubDir = pluginSubDir.replace(self.sourcePluginsPath, '').strip('/') + try: + os.mkdir("%s/%s" % (self.pluginDir, pluginSubDir)) + except OSError: + pass + + os.system('cp "%s" "%s/%s"' % (pluginSource, self.pluginDir, pluginSubDir)) + + self.resolveDependancies("%s/%s/%s" % (self.pluginDir, pluginSubDir, pluginName)) + + def installQtConf(self): + qtConfName = self.appDir + "/qt.conf" + qtConfContent = QT_CONFIG_NOBUNDLE + if self.bundle: + qtConfContent = QT_CONFIG + qtConfName = self.appDir + "/Resources/qt.conf" + + qtConf = open(qtConfName, 'w') + qtConf.write(qtConfContent) + qtConf.close() def resolveDependancies(self, obj): # obj must be either an application binary or a framework library + # print "resolving deps for:", obj for framework, lib in self.determineDependancies(obj): self.installFramework(framework) - self.changeDylPath(obj, lib) + self.changeDylPath(obj, framework, lib) def installFramework(self, framework): # skip if framework is already installed. @@ -86,14 +181,14 @@ class InstallQt(object): except: libname = '' otoolProcess.stdout.close() - if otoolProcess.wait() == 1: # we found some Resource dir or similar -> skip + if otoolProcess.wait() == 1: # we found some Resource dir or similar -> skip continue frameworkpath, libpath = libname.split(frameworkname) if self.bundle: newlibname = "@executable_path/../%s%s" % (frameworkname, libpath) else: newlibname = "@executable_path/%s%s" % (frameworkname, libpath) - #print 'install_name_tool -id "%s" "%s"' % (newlibname, lib) + # print 'install_name_tool -id "%s" "%s"' % (newlibname, lib) os.system('install_name_tool -id "%s" "%s"' % (newlibname, lib)) self.resolveDependancies(lib) @@ -102,37 +197,41 @@ class InstallQt(object): otoolPipe = Popen('otool -L "%s"' % app, shell=True, stdout=PIPE).stdout otoolOutput = [line for line in otoolPipe] otoolPipe.close() - libs = [line.split()[0] for line in otoolOutput[1:] if ("Qt" in line - or "phonon" in line) - and not "@executable_path" in line] - frameworks = [lib[:lib.find(".framework")+len(".framework")] for lib in libs] + libs = [line.split()[0] for line in otoolOutput[1:] if ("Qt" in line or "phonon" in line) and "@executable_path" not in line] + frameworks = [lib[:lib.find(".framework") + len(".framework")] for lib in libs] + frameworks = [framework[framework.rfind('/') + 1:] for framework in frameworks] return zip(frameworks, libs) - - def changeDylPath(self, obj, lib): + def changeDylPath(self, obj, framework, lib): + newlibname = framework + lib.split(framework)[1] if self.bundle: - newlibname = "@executable_path/../Frameworks/%s" % lib + newlibname = "@executable_path/../Frameworks/%s" % newlibname else: - newlibname = "@executable_path/Frameworks/%s" % lib + newlibname = "@executable_path/Frameworks/%s" % newlibname - #print 'install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj) + # print 'install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj) os.system('install_name_tool -change "%s" "%s" "%s"' % (lib, newlibname, obj)) if __name__ == "__main__": if len(sys.argv) < 2: - print "Wrong Argument Count (Syntax: %s [--nobundle] $TARGET_APP)" % sys.argv[0] + print "Wrong Argument Count (Syntax: %s [--nobundle] [--plugins=plugin1,plugin2,...] $TARGET_APP)" % sys.argv[0] sys.exit(1) else: bundle = True + plugins = [] offset = 1 - if sys.argv[1].startswith("--"): - offset = 2 - if sys.argv[1] == "--nobundle": + while offset < len(sys.argv) and sys.argv[offset].startswith("--"): + if sys.argv[offset] == "--nobundle": bundle = False + if sys.argv[offset].startswith("--plugins="): + plugins = sys.argv[offset].split('=')[1].split(',') + + offset += 1 + targetDir = sys.argv[offset] if bundle: targetDir += "/Contents" - InstallQt(targetDir, bundle) + InstallQt(targetDir, bundle, plugins)