diff --git a/ext/toolchain/commands1.py b/ext/toolchain/commands1.py index e4d131cb..43ca4e5a 100644 --- a/ext/toolchain/commands1.py +++ b/ext/toolchain/commands1.py @@ -21,1954 +21,1954 @@ from generators import VisualStudioGenerator, EclipseGenerator, XcodeGenerator, from getopt import gnu_getopt if sys.version_info >= (2, 4): - import subprocess + import subprocess class Toolchain: - - # minimum required version. - # do not change to 2.7, as the build machines are still at 2.6 - # and are a massive pain in the ass to upgrade. - requiredMajor = 2 - requiredMinor = 6 + + # minimum required version. + # do not change to 2.7, as the build machines are still at 2.6 + # and are a massive pain in the ass to upgrade. + requiredMajor = 2 + requiredMinor = 6 - # options used by all commands - globalOptions = 'v' - globalOptionsLong = ['no-prompts', 'verbose', 'skip-gui', 'skip-core', 'skip-tests'] + # options used by all commands + globalOptions = 'v' + globalOptionsLong = ['no-prompts', 'verbose', 'skip-gui', 'skip-core', 'skip-tests'] - # list of valid commands as keys. the values are optarg strings, but most - # are None for now (this is mainly for extensibility) - cmd_opt_dict = { - 'about' : ['', []], - 'setup' : ['g:', ['generator=']], - 'configure' : ['g:dr', ['generator=', 'debug', 'release', 'mac-sdk=', 'mac-deploy=', 'mac-identity=']], - 'build' : ['dr', ['debug', 'release']], - 'clean' : ['dr', ['debug', 'release']], - 'update' : ['', []], - 'install' : ['', []], - 'doxygen' : ['', []], - 'dist' : ['', ['vcredist-dir=', 'qt-dir=']], - 'distftp' : ['', ['host=', 'user=', 'pass=', 'dir=']], - 'kill' : ['', []], - 'usage' : ['', []], - 'revision' : ['', []], - 'reformat' : ['', []], - 'open' : ['', []], - 'genlist' : ['', []], - 'reset' : ['', []], - 'signwin' : ['', ['pfx=', 'pwd=', 'dist']], - 'signmac' : ['', []] - } + # list of valid commands as keys. the values are optarg strings, but most + # are None for now (this is mainly for extensibility) + cmd_opt_dict = { + 'about' : ['', []], + 'setup' : ['g:', ['generator=']], + 'configure' : ['g:dr', ['generator=', 'debug', 'release', 'mac-sdk=', 'mac-deploy=', 'mac-identity=']], + 'build' : ['dr', ['debug', 'release']], + 'clean' : ['dr', ['debug', 'release']], + 'update' : ['', []], + 'install' : ['', []], + 'doxygen' : ['', []], + 'dist' : ['', ['vcredist-dir=', 'qt-dir=']], + 'distftp' : ['', ['host=', 'user=', 'pass=', 'dir=']], + 'kill' : ['', []], + 'usage' : ['', []], + 'revision' : ['', []], + 'reformat' : ['', []], + 'open' : ['', []], + 'genlist' : ['', []], + 'reset' : ['', []], + 'signwin' : ['', ['pfx=', 'pwd=', 'dist']], + 'signmac' : ['', []] + } - # aliases to valid commands - cmd_alias_dict = { - 'info' : 'about', - 'help' : 'usage', - 'package' : 'dist', - 'docs' : 'doxygen', - 'make' : 'build', - 'cmake' : 'configure', - } + # aliases to valid commands + cmd_alias_dict = { + 'info' : 'about', + 'help' : 'usage', + 'package' : 'dist', + 'docs' : 'doxygen', + 'make' : 'build', + 'cmake' : 'configure', + } - def complete_command(self, arg): - completions = [] - - for cmd, optarg in self.cmd_opt_dict.iteritems(): - # if command was matched fully, return only this, so that - # if `dist` is typed, it will return only `dist` and not - # `dist` and `distftp` for example. - if cmd == arg: - return [cmd,] - if cmd.startswith(arg): - completions.append(cmd) - - for alias, cmd in self.cmd_alias_dict.iteritems(): - # don't know if this will work just like above, but it's - # probably worth adding. - if alias == arg: - return [alias,] - if alias.startswith(arg): - completions.append(alias) - - return completions + def complete_command(self, arg): + completions = [] + + for cmd, optarg in self.cmd_opt_dict.iteritems(): + # if command was matched fully, return only this, so that + # if `dist` is typed, it will return only `dist` and not + # `dist` and `distftp` for example. + if cmd == arg: + return [cmd,] + if cmd.startswith(arg): + completions.append(cmd) + + for alias, cmd in self.cmd_alias_dict.iteritems(): + # don't know if this will work just like above, but it's + # probably worth adding. + if alias == arg: + return [alias,] + if alias.startswith(arg): + completions.append(alias) + + return completions - def start_cmd(self, argv): - - cmd_arg = '' - if len(argv) > 1: - cmd_arg = argv[1] - - # change common help args to help command - if cmd_arg in ('--help', '-h', '--usage', '-u', '/?'): - cmd_arg = 'usage' + def start_cmd(self, argv): + + cmd_arg = '' + if len(argv) > 1: + cmd_arg = argv[1] + + # change common help args to help command + if cmd_arg in ('--help', '-h', '--usage', '-u', '/?'): + cmd_arg = 'usage' - completions = self.complete_command(cmd_arg) - - if cmd_arg and len(completions) > 0: + completions = self.complete_command(cmd_arg) + + if cmd_arg and len(completions) > 0: - if len(completions) == 1: + if len(completions) == 1: - # get the only completion (since in this case we have 1) - cmd = completions[0] + # get the only completion (since in this case we have 1) + cmd = completions[0] - # build up the first part of the map (for illustrative purposes) - cmd_map = list() - if cmd_arg != cmd: - cmd_map.append(cmd_arg) - cmd_map.append(cmd) - - # map an alias to the command, and build up the map - if cmd in self.cmd_alias_dict.keys(): - alias = cmd - if cmd_arg == cmd: - cmd_map.append(alias) - cmd = self.cmd_alias_dict[cmd] - cmd_map.append(cmd) - - # show command map to avoid confusion - if len(cmd_map) != 0: - print 'Mapping command: %s' % ' -> '.join(cmd_map) - - self.run_cmd(cmd, argv[2:]) - - return 0 - - else: - print ( - 'Command `%s` too ambiguous, ' - 'could mean any of: %s' - ) % (cmd_arg, ', '.join(completions)) - else: + # build up the first part of the map (for illustrative purposes) + cmd_map = list() + if cmd_arg != cmd: + cmd_map.append(cmd_arg) + cmd_map.append(cmd) + + # map an alias to the command, and build up the map + if cmd in self.cmd_alias_dict.keys(): + alias = cmd + if cmd_arg == cmd: + cmd_map.append(alias) + cmd = self.cmd_alias_dict[cmd] + cmd_map.append(cmd) + + # show command map to avoid confusion + if len(cmd_map) != 0: + print 'Mapping command: %s' % ' -> '.join(cmd_map) + + self.run_cmd(cmd, argv[2:]) + + return 0 + + else: + print ( + 'Command `%s` too ambiguous, ' + 'could mean any of: %s' + ) % (cmd_arg, ', '.join(completions)) + else: - if len(argv) == 1: - print 'No command specified, showing usage.\n' - else: - print 'Command not recognised: %s\n' % cmd_arg - - self.run_cmd('usage') - - # generic error code if not returned sooner - return 1 + if len(argv) == 1: + print 'No command specified, showing usage.\n' + else: + print 'Command not recognised: %s\n' % cmd_arg + + self.run_cmd('usage') + + # generic error code if not returned sooner + return 1 - def run_cmd(self, cmd, argv = []): - - verbose = False - try: - options_pair = self.cmd_opt_dict[cmd] - - options = self.globalOptions + options_pair[0] - - options_long = [] - options_long.extend(self.globalOptionsLong) - options_long.extend(options_pair[1]) - - opts, args = gnu_getopt(argv, options, options_long) - - for o, a in opts: - if o in ('-v', '--verbose'): - verbose = True - - # pass args and optarg data to command handler, which figures out - # how to handle the arguments - handler = CommandHandler(argv, opts, args, verbose) - - # use reflection to get the function pointer - cmd_func = getattr(handler, cmd) - - cmd_func() - except: - if not verbose: - # print friendly error for users - sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n') - sys.exit(1) - else: - # if user wants to be verbose let python do it's thing - raise + def run_cmd(self, cmd, argv = []): + + verbose = False + try: + options_pair = self.cmd_opt_dict[cmd] + + options = self.globalOptions + options_pair[0] + + options_long = [] + options_long.extend(self.globalOptionsLong) + options_long.extend(options_pair[1]) + + opts, args = gnu_getopt(argv, options, options_long) + + for o, a in opts: + if o in ('-v', '--verbose'): + verbose = True + + # pass args and optarg data to command handler, which figures out + # how to handle the arguments + handler = CommandHandler(argv, opts, args, verbose) + + # use reflection to get the function pointer + cmd_func = getattr(handler, cmd) + + cmd_func() + except: + if not verbose: + # print friendly error for users + sys.stderr.write('Error: ' + sys.exc_info()[1].__str__() + '\n') + sys.exit(1) + else: + # if user wants to be verbose let python do it's thing + raise - def run(self, argv): - if sys.version_info < (self.requiredMajor, self.requiredMinor): - print ('Python version must be at least ' + - str(self.requiredMajor) + '.' + str(self.requiredMinor) + ', but is ' + - str(sys.version_info[0]) + '.' + str(sys.version_info[1])) - sys.exit(1) + def run(self, argv): + if sys.version_info < (self.requiredMajor, self.requiredMinor): + print ('Python version must be at least ' + + str(self.requiredMajor) + '.' + str(self.requiredMinor) + ', but is ' + + str(sys.version_info[0]) + '.' + str(sys.version_info[1])) + sys.exit(1) - try: - self.start_cmd(argv) - except KeyboardInterrupt: - print '\n\nUser aborted, exiting.' + try: + self.start_cmd(argv) + except KeyboardInterrupt: + print '\n\nUser aborted, exiting.' class InternalCommands: - - project = 'synergy' - setup_version = 5 # increment to force setup/config - website_url = 'http://symless.com/' + + project = 'synergy' + setup_version = 5 # increment to force setup/config + website_url = 'http://symless.com/' - this_cmd = 'hm' - cmake_cmd = 'cmake' - qmake_cmd = 'qmake' - make_cmd = 'make' - xcodebuild_cmd = 'xcodebuild' - w32_make_cmd = 'nmake' - w32_qt_version = '5.6.1' - defaultTarget = 'release' + this_cmd = 'hm' + cmake_cmd = 'cmake' + qmake_cmd = 'qmake' + make_cmd = 'make' + xcodebuild_cmd = 'xcodebuild' + w32_make_cmd = 'nmake' + w32_qt_version = '5.6.1' + defaultTarget = 'release' - cmake_dir = 'res' - gui_dir = 'src/gui' - doc_dir = 'doc' - extDir = 'ext' + cmake_dir = 'res' + gui_dir = 'src/gui' + doc_dir = 'doc' + extDir = 'ext' - sln_filename = '%s.sln' % project - xcodeproj_filename = '%s.xcodeproj' % project - configDir = 'build' - configFilename = '%s/%s.cfg' % (configDir, this_cmd) - qtpro_filename = 'gui.pro' - doxygen_filename = 'doxygen.cfg' + sln_filename = '%s.sln' % project + xcodeproj_filename = '%s.xcodeproj' % project + configDir = 'build' + configFilename = '%s/%s.cfg' % (configDir, this_cmd) + qtpro_filename = 'gui.pro' + doxygen_filename = 'doxygen.cfg' - cmake_url = 'http://www.cmake.org/cmake/resources/software.html' + cmake_url = 'http://www.cmake.org/cmake/resources/software.html' - # try_chdir(...) and restore_chdir() will use this - prevdir = '' - - # by default, no index specified as arg - generator_id = None - - # by default, prompt user for input - no_prompts = False - - # by default, compile the core - enableMakeCore = True - - # by default, compile the gui - enableMakeGui = True + # try_chdir(...) and restore_chdir() will use this + prevdir = '' + + # by default, no index specified as arg + generator_id = None + + # by default, prompt user for input + no_prompts = False + + # by default, compile the core + enableMakeCore = True + + # by default, compile the gui + enableMakeGui = True - # by default, compile the tests - enableMakeTests = True - - # by default, unknown - macSdk = None - - # by default, unknown - macDeploy = None + # by default, compile the tests + enableMakeTests = True + + # by default, unknown + macSdk = None + + # by default, unknown + macDeploy = None - # by default, unknown - macIdentity = None - - win32_generators = { - 1 : VisualStudioGenerator('14'), - 2 : VisualStudioGenerator('14 Win64'), - 3 : VisualStudioGenerator('10'), - 4 : VisualStudioGenerator('10 Win64'), - 5 : VisualStudioGenerator('9 2008'), - 6 : VisualStudioGenerator('9 2008 Win64'), - 7 : VisualStudioGenerator('8 2005'), - 8 : VisualStudioGenerator('8 2005 Win64'), - } + # by default, unknown + macIdentity = None + + win32_generators = { + 1 : VisualStudioGenerator('14'), + 2 : VisualStudioGenerator('14 Win64'), + 3 : VisualStudioGenerator('10'), + 4 : VisualStudioGenerator('10 Win64'), + 5 : VisualStudioGenerator('9 2008'), + 6 : VisualStudioGenerator('9 2008 Win64'), + 7 : VisualStudioGenerator('8 2005'), + 8 : VisualStudioGenerator('8 2005 Win64'), + } - unix_generators = { - 1 : MakefilesGenerator(), - 2 : EclipseGenerator(), - } + unix_generators = { + 1 : MakefilesGenerator(), + 2 : EclipseGenerator(), + } - darwin_generators = { - 1 : MakefilesGenerator(), - 2 : XcodeGenerator(), - 3 : EclipseGenerator(), - } + darwin_generators = { + 1 : MakefilesGenerator(), + 2 : XcodeGenerator(), + 3 : EclipseGenerator(), + } - def getBuildDir(self, target=''): - return self.getGenerator().getBuildDir(target) + def getBuildDir(self, target=''): + return self.getGenerator().getBuildDir(target) - def getBinDir(self, target=''): - return self.getGenerator().getBinDir(target) + def getBinDir(self, target=''): + return self.getGenerator().getBinDir(target) - def sln_filepath(self): - return '%s\%s' % (self.getBuildDir(), self.sln_filename) + def sln_filepath(self): + return '%s\%s' % (self.getBuildDir(), self.sln_filename) - def xcodeproj_filepath(self, target=''): - return '%s/%s' % (self.getBuildDir(target), self.xcodeproj_filename) - - def usage(self): - app = sys.argv[0] - print ('Usage: %s [-g |-v|--no-prompts|]\n' - '\n' - 'Replace [command] with one of:\n' - ' about Show information about this script\n' - ' setup Runs the initial setup for this script\n' - ' conf Runs cmake (generates project files)\n' - ' open Attempts to open the generated project file\n' - ' build Builds using the platform build chain\n' - ' clean Cleans using the platform build chain\n' - ' kill Kills all synergy processes (run as admin)\n' - ' update Updates the source code from repository\n' - ' revision Display the current source code revision\n' - ' package Create a distribution package (e.g. tar.gz)\n' - ' install Installs the program\n' - ' doxygen Builds doxygen documentation\n' - ' reformat Reformat .cpp and .h files using AStyle\n' - ' genlist Shows the list of available platform generators\n' - ' usage Shows the help screen\n' - '\n' - 'Example: %s conf -g 3' - ) % (app, app) + def xcodeproj_filepath(self, target=''): + return '%s/%s' % (self.getBuildDir(target), self.xcodeproj_filename) + + def usage(self): + app = sys.argv[0] + print ('Usage: %s [-g |-v|--no-prompts|]\n' + '\n' + 'Replace [command] with one of:\n' + ' about Show information about this script\n' + ' setup Runs the initial setup for this script\n' + ' conf Runs cmake (generates project files)\n' + ' open Attempts to open the generated project file\n' + ' build Builds using the platform build chain\n' + ' clean Cleans using the platform build chain\n' + ' kill Kills all synergy processes (run as admin)\n' + ' update Updates the source code from repository\n' + ' revision Display the current source code revision\n' + ' package Create a distribution package (e.g. tar.gz)\n' + ' install Installs the program\n' + ' doxygen Builds doxygen documentation\n' + ' reformat Reformat .cpp and .h files using AStyle\n' + ' genlist Shows the list of available platform generators\n' + ' usage Shows the help screen\n' + '\n' + 'Example: %s conf -g 3' + ) % (app, app) - def configureAll(self, targets, extraArgs=''): + def configureAll(self, targets, extraArgs=''): - # if no mode specified, use default - if len(targets) == 0: - targets += [self.defaultTarget,] + # if no mode specified, use default + if len(targets) == 0: + targets += [self.defaultTarget,] - for target in targets: - self.configure(target) + for target in targets: + self.configure(target) - def configure(self, target='', extraArgs=''): + def configure(self, target='', extraArgs=''): - # ensure latest setup and do not ask config for generator (only fall - # back to prompt if not specified as arg) - self.ensure_setup_latest() + # ensure latest setup and do not ask config for generator (only fall + # back to prompt if not specified as arg) + self.ensure_setup_latest() - if sys.platform == "darwin": - config = self.getConfig() - - if self.macSdk: - config.set('hm', 'macSdk', self.macSdk) - elif config.has_option("hm", "macSdk"): - self.macSdk = config.get('hm', 'macSdk') - - if self.macDeploy: - config.set('hm', 'macDeploy', self.macDeploy) - elif config.has_option("hm", "macDeploy"): - self.macSdk = config.get('hm', 'macDeploy') + if sys.platform == "darwin": + config = self.getConfig() + + if self.macSdk: + config.set('hm', 'macSdk', self.macSdk) + elif config.has_option("hm", "macSdk"): + self.macSdk = config.get('hm', 'macSdk') + + if self.macDeploy: + config.set('hm', 'macDeploy', self.macDeploy) + elif config.has_option("hm", "macDeploy"): + self.macSdk = config.get('hm', 'macDeploy') - if self.macIdentity: - config.set('hm', 'macIdentity', self.macIdentity) - elif config.has_option("hm", "macIdentity"): - self.macIdentity = config.get('hm', 'macIdentity') - - self.write_config(config) - - if not self.macSdk: - raise Exception("Arg missing: --mac-sdk "); - - if not self.macDeploy: - self.macDeploy = self.macSdk + if self.macIdentity: + config.set('hm', 'macIdentity', self.macIdentity) + elif config.has_option("hm", "macIdentity"): + self.macIdentity = config.get('hm', 'macIdentity') + + self.write_config(config) + + if not self.macSdk: + raise Exception("Arg missing: --mac-sdk "); + + if not self.macDeploy: + self.macDeploy = self.macSdk - if not self.macIdentity: - raise Exception("Arg missing: --mac-identity "); - - sdkDir = self.getMacSdkDir() - if not os.path.exists(sdkDir): - raise Exception("Mac SDK not found at: " + sdkDir) - - os.environ["MACOSX_DEPLOYMENT_TARGET"] = self.macSdk - - # default is release - if target == '': - print 'Defaulting target to: ' + self.defaultTarget - target = self.defaultTarget - - # allow user to skip core compile - if self.enableMakeCore: - self.configureCore(target, extraArgs) - - # allow user to skip gui compile - if self.enableMakeGui: - self.configureGui(target, extraArgs) - - self.setConfRun(target) + if not self.macIdentity: + raise Exception("Arg missing: --mac-identity "); + + sdkDir = self.getMacSdkDir() + if not os.path.exists(sdkDir): + raise Exception("Mac SDK not found at: " + sdkDir) + + os.environ["MACOSX_DEPLOYMENT_TARGET"] = self.macSdk + + # default is release + if target == '': + print 'Defaulting target to: ' + self.defaultTarget + target = self.defaultTarget + + # allow user to skip core compile + if self.enableMakeCore: + self.configureCore(target, extraArgs) + + # allow user to skip gui compile + if self.enableMakeGui: + self.configureGui(target, extraArgs) + + self.setConfRun(target) - def configureCore(self, target="", extraArgs=""): - - # ensure that we have access to cmake - _cmake_cmd = self.persist_cmake() - - # now that we know we've got the latest setup, we can ask the config - # file for the generator (but again, we only fall back to this if not - # specified as arg). - generator = self.getGenerator() - - if generator != self.findGeneratorFromConfig(): - print('Generator changed, running setup.') - self.setup(target) - - cmake_args = '' - if generator.cmakeName != '': - cmake_args += ' -G "' + generator.cmakeName + '"' + def configureCore(self, target="", extraArgs=""): + + # ensure that we have access to cmake + _cmake_cmd = self.persist_cmake() + + # now that we know we've got the latest setup, we can ask the config + # file for the generator (but again, we only fall back to this if not + # specified as arg). + generator = self.getGenerator() + + if generator != self.findGeneratorFromConfig(): + print('Generator changed, running setup.') + self.setup(target) + + cmake_args = '' + if generator.cmakeName != '': + cmake_args += ' -G "' + generator.cmakeName + '"' - # for makefiles always specify a build type (debug, release, etc) - if generator.cmakeName.find('Unix Makefiles') != -1: - cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize() - - if sys.platform == "darwin": - macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk) - if not macSdkMatch: - raise Exception("unknown osx version: " + self.macSdk) + # for makefiles always specify a build type (debug, release, etc) + if generator.cmakeName.find('Unix Makefiles') != -1: + cmake_args += ' -DCMAKE_BUILD_TYPE=' + target.capitalize() + + if sys.platform == "darwin": + macSdkMatch = re.match("(\d+)\.(\d+)", self.macSdk) + if not macSdkMatch: + raise Exception("unknown osx version: " + self.macSdk) - if generator.cmakeName.find('Unix Makefiles') == -1: - sdkDir = self.getMacSdkDir() - cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir - cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macDeploy + if generator.cmakeName.find('Unix Makefiles') == -1: + sdkDir = self.getMacSdkDir() + cmake_args += " -DCMAKE_OSX_SYSROOT=" + sdkDir + cmake_args += " -DCMAKE_OSX_DEPLOYMENT_TARGET=" + self.macDeploy - cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1) - cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2) + cmake_args += " -DOSX_TARGET_MAJOR=" + macSdkMatch.group(1) + cmake_args += " -DOSX_TARGET_MINOR=" + macSdkMatch.group(2) - cmake_args += " -DDISABLE_TESTS=" + str(int(not self.enableMakeTests)) - - # if not visual studio, use parent dir - sourceDir = generator.getSourceDir() + cmake_args += " -DDISABLE_TESTS=" + str(int(not self.enableMakeTests)) + + # if not visual studio, use parent dir + sourceDir = generator.getSourceDir() - if extraArgs != '': - cmake_args += ' ' + extraArgs + if extraArgs != '': + cmake_args += ' ' + extraArgs - cmake_cmd_string = _cmake_cmd + cmake_args + ' ' + sourceDir - - # Run from build dir so we have an out-of-source build. - self.try_chdir(self.getBuildDir(target)) + cmake_cmd_string = _cmake_cmd + cmake_args + ' ' + sourceDir + + # Run from build dir so we have an out-of-source build. + self.try_chdir(self.getBuildDir(target)) - print "CMake command: " + cmake_cmd_string - err = os.system(cmake_cmd_string) + print "CMake command: " + cmake_cmd_string + err = os.system(cmake_cmd_string) - self.restore_chdir() + self.restore_chdir() - if generator.cmakeName.find('Eclipse') != -1: - self.fixCmakeEclipseBug() - - if err != 0: - raise Exception('CMake encountered error: ' + str(err)) + if generator.cmakeName.find('Eclipse') != -1: + self.fixCmakeEclipseBug() + + if err != 0: + raise Exception('CMake encountered error: ' + str(err)) - def configureGui(self, target="", extraArgs=""): - - # make sure we have qmake - self.persist_qmake() - - qmake_cmd_string = self.qmake_cmd + " " + self.qtpro_filename + " -r" + def configureGui(self, target="", extraArgs=""): + + # make sure we have qmake + self.persist_qmake() + + qmake_cmd_string = self.qmake_cmd + " " + self.qtpro_filename + " -r" - if sys.platform == "darwin": - - # create makefiles on mac (not xcode). - qmake_cmd_string += " -spec macx-g++" - - (major, minor) = self.getMacVersion() - if major == 10 and minor <= 4: - # 10.4: universal (intel and power pc) - qmake_cmd_string += ' CONFIG+="ppc i386"' - - libs = ( - "-framework ApplicationServices " - "-framework Security " - "-framework cocoa") - - if major == 10 and minor >= 6: - libs += " -framework ServiceManagement" - - qmake_cmd_string += " \"MACX_LIBS=%s\" " % libs - - sdkDir = self.getMacSdkDir() - shortForm = "macosx" + self.macSdk - version = str(major) + "." + str(minor) + if sys.platform == "darwin": + + # create makefiles on mac (not xcode). + qmake_cmd_string += " -spec macx-g++" + + (major, minor) = self.getMacVersion() + if major == 10 and minor <= 4: + # 10.4: universal (intel and power pc) + qmake_cmd_string += ' CONFIG+="ppc i386"' + + libs = ( + "-framework ApplicationServices " + "-framework Security " + "-framework cocoa") + + if major == 10 and minor >= 6: + libs += " -framework ServiceManagement" + + qmake_cmd_string += " \"MACX_LIBS=%s\" " % libs + + sdkDir = self.getMacSdkDir() + shortForm = "macosx" + self.macSdk + version = str(major) + "." + str(minor) - qmake_cmd_string += " QMAKE_MACOSX_DEPLOYMENT_TARGET=" + self.macDeploy + qmake_cmd_string += " QMAKE_MACOSX_DEPLOYMENT_TARGET=" + self.macDeploy - (qMajor, qMinor, qRev) = self.getQmakeVersion() - if qMajor <= 4: - # 4.6: qmake takes full sdk dir. - qmake_cmd_string += " QMAKE_MAC_SDK=" + sdkDir - else: - # 5.2: now we need to use the .path setting. - qmake_cmd_string += " QMAKE_MAC_SDK=" + shortForm - qmake_cmd_string += " QMAKE_MAC_SDK." + shortForm + ".path=" + sdkDir + (qMajor, qMinor, qRev) = self.getQmakeVersion() + if qMajor <= 4: + # 4.6: qmake takes full sdk dir. + qmake_cmd_string += " QMAKE_MAC_SDK=" + sdkDir + else: + # 5.2: now we need to use the .path setting. + qmake_cmd_string += " QMAKE_MAC_SDK=" + shortForm + qmake_cmd_string += " QMAKE_MAC_SDK." + shortForm + ".path=" + sdkDir - qmake_cmd_string += " QMAKE_VERSION_STAGE=" + self.getVersionStage() - qmake_cmd_string += " QMAKE_VERSION_REVISION=" + self.getGitRevision() - print "QMake command: " + qmake_cmd_string - - # run qmake from the gui dir - self.try_chdir(self.gui_dir) - err = os.system(qmake_cmd_string) - self.restore_chdir() - - if err != 0: - raise Exception('QMake encountered error: ' + str(err)) + qmake_cmd_string += " QMAKE_VERSION_STAGE=" + self.getVersionStage() + qmake_cmd_string += " QMAKE_VERSION_REVISION=" + self.getGitRevision() + print "QMake command: " + qmake_cmd_string + + # run qmake from the gui dir + self.try_chdir(self.gui_dir) + err = os.system(qmake_cmd_string) + self.restore_chdir() + + if err != 0: + raise Exception('QMake encountered error: ' + str(err)) - def getQmakeVersion(self): - version = commands.getoutput("qmake --version") - result = re.search('(\d+)\.(\d+)\.(\d)', version) - - if not result: - raise Exception("Could not get qmake version.") + def getQmakeVersion(self): + version = commands.getoutput("qmake --version") + result = re.search('(\d+)\.(\d+)\.(\d)', version) + + if not result: + raise Exception("Could not get qmake version.") - major = int(result.group(1)) - minor = int(result.group(2)) - rev = int(result.group(3)) - - return (major, minor, rev) - - def getMacSdkDir(self): - sdkName = "macosx" + self.macSdk - - # Ideally we'll use xcrun (which is influenced by $DEVELOPER_DIR), then try a couple - # fallbacks to known paths if xcrun is not available - status, sdkPath = commands.getstatusoutput("xcrun --show-sdk-path --sdk " + sdkName) - if status == 0 and sdkPath: - return sdkPath - - developerDir = os.getenv("DEVELOPER_DIR") - if not developerDir: - developerDir = "/Applications/Xcode.app/Contents/Developer" - - sdkDirName = sdkName.replace("macosx", "MacOSX") - sdkPath = developerDir + "/Platforms/MacOSX.platform/Developer/SDKs/" + sdkDirName + ".sdk" - if os.path.exists(sdkPath): - return sdkPath - - # return os.popen('xcodebuild -version -sdk macosx' + self.macSdk + ' Path').read().strip() - return "/Developer/SDKs/" + sdkDirName + ".sdk" - - # http://tinyurl.com/cs2rxxb - def fixCmakeEclipseBug(self): - print "Fixing CMake Eclipse bugs..." - - file = open('.project', 'r+') - content = file.read() - pattern = re.compile('\s+.+', re.S) - content = pattern.sub('', content) - file.seek(0) - file.write(content) - file.truncate() - file.close() - - def persist_cmake(self): - # even though we're running `cmake --version`, we're only doing this for the 0 return - # code; we don't care about the version, since CMakeLists worrys about this for us. - err = os.system('%s --version' % self.cmake_cmd) - - if err != 0: - # if return code from cmake is not 0, then either something has - # gone terribly wrong with --version, or it genuinely doesn't exist. - print ('Could not find `%s` in system path.\n' - 'Download the latest version from:\n %s') % ( - self.cmake_cmd, self.cmake_url) - raise Exception('Cannot continue without CMake.') - else: - return self.cmake_cmd - - def persist_qt(self): - self.persist_qmake() - - def persist_qmake(self): - # cannot use subprocess on < python 2.4 - if sys.version_info < (2, 4): - return - - try: - p = subprocess.Popen( - [self.qmake_cmd, '--version'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - except: - print >> sys.stderr, 'Error: Could not find qmake.' - if sys.platform == 'win32': # windows devs usually need hints ;) - print ( - 'Suggestions:\n' - '1. Ensure that qmake.exe exists in your system path.\n' - '2. Try to download Qt 5.6\n') - raise Exception('Cannot continue without qmake.') - - stdout, stderr = p.communicate() - if p.returncode != 0: - raise Exception('Could not test for qmake: %s' % stderr) - else: - m = re.search('.*Using Qt version (\d+\.\d+\.\d+).*', stdout) - if m: - if sys.platform == 'win32': - ver = m.group(1) - if ver != self.w32_qt_version: # TODO: test properly - print >> sys.stderr, ( - 'Warning: Not using supported Qt version %s' - ' (your version is %s).' - ) % (self.w32_qt_version, ver) - else: - pass # any version should be ok for other platforms - else: - raise Exception('Could not find qmake version.') - - def ensureConfHasRun(self, target, skipConfig): - if self.hasConfRun(target): - print 'Skipping config for target: ' + target - skipConfig = True - - if not skipConfig: - self.configure(target) - - def build(self, targets=[], skipConfig=False): - - # if no mode specified, use default - if len(targets) == 0: - targets += [self.defaultTarget,] - - self.ensure_setup_latest() - - self.loadConfig() - - # allow user to skip core compile - if self.enableMakeCore: - self.makeCore(targets) - - # allow user to skip gui compile - if self.enableMakeGui: - self.makeGui(targets) - - def loadConfig(self): - config = self.getConfig() - - if config.has_option("hm", "macSdk"): - self.macSdk = config.get("hm", "macSdk") - - if config.has_option("hm", "macDeploy"): - self.macDeploy = config.get("hm", "macDeploy") - - if config.has_option("hm", "macIdentity"): - self.macIdentity = config.get("hm", "macIdentity") - - def makeCore(self, targets): - - generator = self.getGeneratorFromConfig().cmakeName - - if self.macSdk: - os.environ["MACOSX_DEPLOYMENT_TARGET"] = self.macSdk - - if generator.find('Unix Makefiles') != -1: - for target in targets: - self.runBuildCommand(self.make_cmd, target) - else: - for target in targets: - if generator.startswith('Visual Studio'): - self.run_vcbuild(generator, target, self.sln_filepath()) - elif generator == 'Xcode': - cmd = self.xcodebuild_cmd + ' -configuration ' + target.capitalize() - self.runBuildCommand(cmd, target) - else: - raise Exception('Build command not supported with generator: ' + generator) - - def makeGui(self, targets, args=""): - for target in targets: - - if sys.platform == 'win32': - - gui_make_cmd = self.w32_make_cmd + ' ' + target + args - print 'Make GUI command: ' + gui_make_cmd - - self.try_chdir(self.gui_dir) - err = os.system(gui_make_cmd) - self.restore_chdir() - - if err != 0: - raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) - - elif sys.platform in ['linux2', 'sunos5', 'freebsd7', 'darwin']: - - gui_make_cmd = self.make_cmd + " -w" + args - print 'Make GUI command: ' + gui_make_cmd - - # start with a clean app bundle - targetDir = self.getGenerator().getBinDir(target) - bundleTargetDir = targetDir + '/Synergy.app' - if os.path.exists(bundleTargetDir): - shutil.rmtree(bundleTargetDir) - - binDir = self.getGenerator().binDir - bundleTempDir = binDir + '/Synergy.app' - if os.path.exists(bundleTempDir): - shutil.rmtree(bundleTempDir) - - self.try_chdir(self.gui_dir) - err = os.system(gui_make_cmd) - self.restore_chdir() - - if err != 0: - raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) - - if sys.platform == 'darwin' and not "clean" in args: - self.macPostGuiMake(target) - - self.fixQtFrameworksLayout(target) - else: - raise Exception('Unsupported platform: ' + sys.platform) - - def macPostGuiMake(self, target): - bundle = 'Synergy.app' - binDir = self.getGenerator().binDir - targetDir = self.getGenerator().getBinDir(target) - bundleTempDir = binDir + '/' + bundle - bundleTargetDir = targetDir + '/' + bundle - - if os.path.exists(bundleTempDir): - shutil.move(bundleTempDir, bundleTargetDir) - - if self.enableMakeCore: - # copy core binaries into the bundle, since the gui - # now looks for the binaries in the current app dir. - - bundleBinDir = bundleTargetDir + "/Contents/MacOS/" - shutil.copy(targetDir + "/synergyc", bundleBinDir) - shutil.copy(targetDir + "/synergys", bundleBinDir) - shutil.copy(targetDir + "/syntool", bundleBinDir) - - self.loadConfig() - if not self.macIdentity: - raise Exception("run config with --mac-identity") - - if self.enableMakeGui: - # use qt to copy libs to bundle so no dependencies are needed. do not create a - # dmg at this point, since we need to sign it first, and then create our own - # after signing (so that qt does not affect the signed app bundle). - bin = "macdeployqt Synergy.app -verbose=2" - self.try_chdir(targetDir) - err = os.system(bin) - self.restore_chdir() - print bundleTargetDir - if err != 0: - raise Exception(bin + " failed with error: " + str(err)) - - frameworkRootDir = commands.getoutput("qmake -query QT_INSTALL_LIBS") - - target = bundleTargetDir + "/Contents/Frameworks" - - # copy the missing Info.plist files for the frameworks. - for root, dirs, files in os.walk(target): - for dir in dirs: - if dir.startswith("Qt"): - shutil.copy( - frameworkRootDir + "/" + dir + "/Contents/Info.plist", - target + "/" + dir + "/Resources/") - - def symlink(self, source, target): - if not os.path.exists(target): - os.symlink(source, target) - - def move(self, source, target): - if os.path.exists(source): - shutil.move(source, target) - - def fixQtFrameworksLayout(self, target): - # reorganize Qt frameworks layout on Mac 10.9.5 or later - # http://goo.gl/BFnQ8l - # QtCore example: - # QtCore.framework/ - # QtCore -> Versions/Current/QtCore - # Resources -> Versions/Current/Resources - # Versions/ - # Current -> 5 - # 5/ - # QtCore - # Resources/ - # Info.plist - targetDir = self.getGenerator().getBinDir(target) - - target = targetDir + "/Synergy.app/Contents/Frameworks" - (major, minor) = self.getMacVersion() - if major == 10: - if minor >= 9: - for root, dirs, files in os.walk(target): - for dir in dirs: - if dir.startswith("Qt"): - self.try_chdir(target + "/" + dir +"/Versions") - self.symlink("5", "Current") - self.move("../Resources", "5") - self.restore_chdir() - - self.try_chdir(target + "/" + dir) - dot = dir.find('.') - frameworkName = dir[:dot] - self.symlink("Versions/Current/" + frameworkName, frameworkName) - self.symlink("Versions/Current/Resources", "Resources") - self.restore_chdir() - - def signmac(self): - self.loadConfig() - if not self.macIdentity: - raise Exception("run config with --mac-identity") - - self.try_chdir("bin/Release/") - err = os.system( - 'codesign --deep -fs "' + self.macIdentity + '" Synergy.app') - self.restore_chdir() - - if err != 0: - raise Exception("codesign failed with error: " + str(err)) - - def signwin(self, pfx, pwdFile, dist): - generator = self.getGeneratorFromConfig().cmakeName - if not generator.startswith('Visual Studio'): - raise Exception('only windows is supported') - - f = open(pwdFile) - lines = f.readlines() - f.close() - pwd = lines[0] - - if (dist): - self.signFile(pfx, pwd, 'bin/Release', self.getDistFilename('win')) - else: - self.signFile(pfx, pwd, 'bin/Release', 'synergy.exe') - self.signFile(pfx, pwd, 'bin/Release', 'synergyc.exe') - self.signFile(pfx, pwd, 'bin/Release', 'synergys.exe') - self.signFile(pfx, pwd, 'bin/Release', 'synergyd.exe') - self.signFile(pfx, pwd, 'bin/Release', 'syntool.exe') - self.signFile(pfx, pwd, 'bin/Release', 'synwinhk.dll') - - def signFile(self, pfx, pwd, dir, file): - self.try_chdir(dir) - err = os.system( - 'signtool sign' - ' /f ' + pfx + - ' /p ' + pwd + - ' /t http://timestamp.verisign.com/scripts/timstamp.dll ' + - file) - self.restore_chdir() - - if err != 0: - raise Exception("signtool failed with error: " + str(err)) - - def runBuildCommand(self, cmd, target): - - self.try_chdir(self.getBuildDir(target)) - err = os.system(cmd) - self.restore_chdir() - - if err != 0: - raise Exception(cmd + ' failed: ' + str(err)) - - def clean(self, targets=[]): - - # if no mode specified, use default - if len(targets) == 0: - targets += [self.defaultTarget,] - - # allow user to skip core clean - if self.enableMakeCore: - self.cleanCore(targets) - - # allow user to skip qui clean - if self.enableMakeGui: - self.cleanGui(targets) - - def cleanCore(self, targets): - generator = self.getGeneratorFromConfig().cmakeName - - if generator.startswith('Visual Studio'): - # special case for version 10 and above, use new /target:clean - if generator.startswith('Visual Studio 10') or generator.startswith('Visual Studio 14'): - for target in targets: - self.run_vcbuild(generator, target, self.sln_filepath(), '/target:clean') - - # any other version of visual studio, use /clean - elif generator.startswith('Visual Studio'): - for target in targets: - self.run_vcbuild(generator, target, self.sln_filepath(), '/clean') - - else: - cmd = '' - if generator == "Unix Makefiles": - print 'Cleaning with GNU Make...' - cmd = self.make_cmd - elif generator == 'Xcode': - print 'Cleaning with Xcode...' - cmd = self.xcodebuild_cmd - else: - raise Exception('Not supported with generator: ' + generator) - - for target in targets: - self.try_chdir(self.getBuildDir(target)) - err = os.system(cmd + ' clean') - self.restore_chdir() - - if err != 0: - raise Exception('Clean failed: ' + str(err)) - - def cleanGui(self, targets): - self.makeGui(targets, " clean") - - def open(self): - generator = self.getGeneratorFromConfig().cmakeName - if generator.startswith('Visual Studio'): - print 'Opening with %s...' % generator - self.open_internal(self.sln_filepath()) - - elif generator.startswith('Xcode'): - print 'Opening with %s...' % generator - self.open_internal(self.xcodeproj_filepath(), 'open') - - else: - raise Exception('Not supported with generator: ' + generator) - - def update(self): - print "Running Subversion update..." - err = os.system('svn update') - if err != 0: - raise Exception('Could not update from repository with error code code: ' + str(err)) - - def revision(self): - print self.find_revision() - - def find_revision(self): - return self.getGitRevision() - - def getGitRevision(self): - if sys.version_info < (2, 4): - raise Exception("Python 2.4 or greater required.") - - p = subprocess.Popen( - ["git", "log", "--pretty=format:%h", "-n", "1"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - stdout, stderr = p.communicate() - - if p.returncode != 0: - raise Exception('Could not get revision, git error: ' + str(p.returncode)) - - return stdout.strip() - - def getGitBranchName(self): - if sys.version_info < (2, 4): - raise Exception("Python 2.4 or greater required.") - - p = subprocess.Popen( - ["git", "rev-parse", "--abbrev-ref", "HEAD"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - stdout, stderr = p.communicate() - - if p.returncode != 0: - raise Exception('Could not get branch name, git error: ' + str(p.returncode)) - - result = stdout.strip() - - # sometimes, git will prepend "heads/" infront of the branch name, - # remove this as it's not useful to us and causes ftp issues. - result = re.sub("heads/", "", result) - - return result - - def find_revision_svn(self): - if sys.version_info < (2, 4): - stdout = commands.getoutput('svn info') - else: - p = subprocess.Popen(['svn', 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - - if p.returncode != 0: - raise Exception('Could not get revision - svn info failed with code: ' + str(p.returncode)) - - m = re.search('.*Revision: (\d+).*', stdout) - if not m: - raise Exception('Could not find revision number in svn info output.') - - return m.group(1) - - def kill(self): - if sys.platform == 'win32': - return os.system('taskkill /F /FI "IMAGENAME eq synergy*"') - else: - raise Exception('Not implemented for platform: ' + sys.platform) - - def doxygen(self): - self.enableMakeGui = False - - # The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in - self.configure(self.defaultTarget, '-DCONF_DOXYGEN:BOOL=TRUE') - - err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename)) - - if err != 0: - raise Exception('doxygen failed with error code: ' + str(err)) - - def dist(self, type, vcRedistDir, qtDir): - - # Package is supported by default. - package_unsupported = False - unixTarget = self.defaultTarget - - if type == '' or type == None: - self.dist_usage() - return - - moveExt = '' - - if type == 'src': - self.distSrc() - - elif type == 'rpm': - if sys.platform == 'linux2': - self.distRpm() - else: - package_unsupported = True - - elif type == 'deb': - if sys.platform == 'linux2': - self.distDeb() - else: - package_unsupported = True - - elif type == 'win': - if sys.platform == 'win32': - #self.distNsis(vcRedistDir, qtDir) - self.distWix() - else: - package_unsupported = True - - elif type == 'mac': - if sys.platform == 'darwin': - self.distMac() - else: - package_unsupported = True - - else: - raise Exception('Package type not supported: ' + type) - - if moveExt != '': - self.unixMove( - self.getGenerator().buildDir + '/release/*.' + moveExt, - self.getGenerator().binDir) - - if package_unsupported: - raise Exception( - ("Package type, '%s' is not supported for platform, '%s'") - % (type, sys.platform)) - - def distRpm(self): - rpmDir = self.getGenerator().buildDir + '/rpm' - if os.path.exists(rpmDir): - shutil.rmtree(rpmDir) - - os.makedirs(rpmDir) - - templateFile = open(self.cmake_dir + '/synergy.spec.in') - template = templateFile.read() - - template = template.replace('${in:version}', self.getVersionNumber()) - - specPath = rpmDir + '/synergy.spec' - - specFile = open(specPath, 'w') - specFile.write(template) - specFile.close() - - target = '../../bin/synergy-%s-%s.rpm' % ( - self.getVersionForFilename(), self.getLinuxPlatform()) - - try: - self.try_chdir(rpmDir) - cmd = 'rpmbuild -bb --define "_topdir `pwd`" synergy.spec' - print "Command: " + cmd - err = os.system(cmd) - if err != 0: - raise Exception('rpmbuild failed: ' + str(err)) - - self.unixMove('RPMS/*/*.rpm', target) - - cmd = 'rpmlint ' + target - print "Command: " + cmd - err = os.system(cmd) - if err != 0: - raise Exception('rpmlint failed: ' + str(err)) - - finally: - self.restore_chdir() - - def distDeb(self): - buildDir = self.getGenerator().buildDir - binDir = self.getGenerator().binDir - resDir = self.cmake_dir - - package = '%s-%s-%s' % ( - self.project, - self.getVersionForFilename(), - self.getLinuxPlatform()) - - debDir = '%s/deb' % buildDir - if os.path.exists(debDir): - shutil.rmtree(debDir) - - metaDir = '%s/%s/DEBIAN' % (debDir, package) - os.makedirs(metaDir) - - templateFile = open(resDir + '/deb/control.in') - template = templateFile.read() - - template = template.replace('${in:version}', - self.getVersionNumber()) - - template = template.replace('${in:arch}', - self.getDebianArch()) - - controlPath = '%s/control' % metaDir - - controlFile = open(controlPath, 'w') - controlFile.write(template) - controlFile.close() - - targetBin = '%s/%s/usr/bin' % (debDir, package) - targetShare = '%s/%s/usr/share' % (debDir, package) - targetApplications = "%s/applications" % targetShare - targetIcons = "%s/icons" % targetShare - targetDocs = "%s/doc/%s" % (targetShare, self.project) - - os.makedirs(targetBin) - os.makedirs(targetApplications) - os.makedirs(targetIcons) - os.makedirs(targetDocs) - - for root, dirs, files in os.walk(debDir): - for d in dirs: - os.chmod(os.path.join(root, d), 0o0755) - - binFiles = ['synergy', 'synergyc', 'synergys', 'synergyd', 'syntool'] - for f in binFiles: - shutil.copy("%s/%s" % (binDir, f), targetBin) - target = "%s/%s" % (targetBin, f) - os.chmod(target, 0o0755) - err = os.system("strip " + target) - if err != 0: - raise Exception('strip failed: ' + str(err)) - - shutil.copy("%s/synergy.desktop" % resDir, targetApplications) - shutil.copy("%s/synergy.ico" % resDir, targetIcons) - - docTarget = "%s/doc/%s" % (targetShare, self.project) - - copyrightPath = "%s/deb/copyright" % resDir - shutil.copy(copyrightPath, docTarget) - - shutil.copy("%s/deb/changelog" % resDir, docTarget) - os.system("gzip -9 %s/changelog" % docTarget) - if err != 0: - raise Exception('gzip failed: ' + str(err)) - - for root, dirs, files in os.walk(targetShare): - for f in files: - os.chmod(os.path.join(root, f), 0o0644) - - target = '../../bin/%s.deb' % package - - try: - self.try_chdir(debDir) - - # TODO: consider dpkg-buildpackage (higher level tool) - cmd = 'fakeroot dpkg-deb --build %s' % package - print "Command: " + cmd - err = os.system(cmd) - if err != 0: - raise Exception('dpkg-deb failed: ' + str(err)) - - cmd = 'lintian %s.deb' % package - print "Command: " + cmd - err = os.system(cmd) - if err != 0: - raise Exception('lintian failed: ' + str(err)) - - self.unixMove('*.deb', target) - finally: - self.restore_chdir() - - def distSrc(self): - name = '%s-%s-%s' % ( - self.project, - self.getVersionForFilename(), - 'Source') - - exportPath = self.getGenerator().buildDir + '/' + name - - if os.path.exists(exportPath): - print "Removing existing export..." - shutil.rmtree(exportPath) - - os.mkdir(exportPath) - - cmd = "git archive %s | tar -x -C %s" % ( - self.getGitBranchName(), exportPath) - - print 'Exporting repository to: ' + exportPath - err = os.system(cmd) - if err != 0: - raise Exception('Repository export failed: ' + str(err)) - - packagePath = '../' + self.getGenerator().binDir + '/' + name + '.tar.gz' - - try: - self.try_chdir(self.getGenerator().buildDir) - print 'Packaging to: ' + packagePath - err = os.system('tar cfvz ' + packagePath + ' ' + name) - if err != 0: - raise Exception('Package failed: ' + str(err)) - finally: - self.restore_chdir() - - def unixMove(self, source, dest): - print 'Moving ' + source + ' to ' + dest - err = os.system('mv ' + source + ' ' + dest) - if err != 0: - raise Exception('Package failed: ' + str(err)) - - def distMac(self): - self.loadConfig() - binDir = self.getGenerator().getBinDir('Release') - name = "Synergy" - dist = binDir + "/" + name - - # ensure dist dir is clean - if os.path.exists(dist): - shutil.rmtree(dist) - - os.makedirs(dist) - shutil.move(binDir + "/" + name + ".app", dist + "/" + name + ".app") - - self.try_chdir(dist) - err = os.system("ln -s /Applications") - self.restore_chdir() - - fileName = "%s-%s-%s.dmg" % ( - self.project, - self.getVersionForFilename(), - self.getMacPackageName()) - - cmd = "hdiutil create " + fileName + " -srcfolder ./" + name + "/ -ov" - - self.try_chdir(binDir) - err = os.system(cmd) - self.restore_chdir() - - def distWix(self): - generator = self.getGeneratorFromConfig().cmakeName - - arch = 'x86' - if generator.endswith('Win64'): - arch = 'x64' - - version = self.getVersionNumber() - args = "/p:DefineConstants=\"Version=%s\"" % version - - self.run_vcbuild( - generator, 'release', 'synergy.sln', args, - 'src/setup/win32/', 'x86') - - filename = "%s-%s-Windows-%s.msi" % ( - self.project, - self.getVersionForFilename(), - arch) - - old = "bin/Release/synergy.msi" - new = "bin/Release/%s" % (filename) - - try: - os.remove(new) - except OSError: - pass - - os.rename(old, new) - - def distNsis(self, vcRedistDir, qtDir): - - if vcRedistDir == '': - raise Exception( - 'VC++ redist dir path not specified (--vcredist-dir).') - - if qtDir == '': - raise Exception( - 'QT SDK dir path not specified (--qt-dir).') - - generator = self.getGeneratorFromConfig().cmakeName - - arch = 'x86' - installDirVar = '$PROGRAMFILES32' - - if generator.endswith('Win64'): - arch = 'x64' - installDirVar = '$PROGRAMFILES64' - - templateFile = open(self.cmake_dir + '\Installer.nsi.in') - template = templateFile.read() - - template = template.replace('${in:version}', self.getVersionNumber()) - template = template.replace('${in:arch}', arch) - template = template.replace('${in:vcRedistDir}', vcRedistDir) - template = template.replace('${in:qtDir}', qtDir) - template = template.replace('${in:installDirVar}', installDirVar) - - nsiPath = self.getGenerator().buildDir + '\Installer.nsi' - nsiFile = open(nsiPath, 'w') - nsiFile.write(template) - nsiFile.close() - - command = 'makensis ' + nsiPath - print 'NSIS command: ' + command - err = os.system(command) - if err != 0: - raise Exception('Package failed: ' + str(err)) - - def getVersionNumber(self): - cmakeFile = open('CMakeLists.txt') - cmake = cmakeFile.read() - - majorRe = re.search('VERSION_MAJOR (\d+)', cmake) - major = majorRe.group(1) - - minorRe = re.search('VERSION_MINOR (\d+)', cmake) - minor = minorRe.group(1) - - revRe = re.search('VERSION_REV (\d+)', cmake) - rev = revRe.group(1) - - return "%s.%s.%s" % (major, minor, rev) - - def getVersionStage(self): - cmakeFile = open('CMakeLists.txt') - cmake = cmakeFile.read() - - stageRe = re.search('VERSION_STAGE (\w+)', cmake) - return stageRe.group(1) - - def getVersionForFilename(self): - versionStage = self.getVersionStage() - gitBranch = self.getGitBranchName() - gitRevision = self.getGitRevision() - return "%s-%s-%s" % (gitBranch, versionStage, gitRevision) - - def distftp(self, type, ftp): - if not type: - raise Exception('Platform type not specified.') - - self.loadConfig() - - binDir = self.getGenerator().getBinDir('Release') - - filename = self.getDistFilename(type) - packageSource = binDir + '/' + filename - packageTarget = filename - ftp.upload(packageSource, packageTarget) - - def getLibraryDistFilename(self, type, dir, name): - (platform, packageExt, libraryExt) = self.getDistributePlatformInfo(type) - firstPart = '%s-%s-%s' % (name, self.getVersionForFilename(), platform) - - filename = '%s.%s' % (firstPart, libraryExt) - if type == 'rpm' or type == 'deb': - # linux is a bit special, include dist type (deb/rpm in filename) - filename = '%s-%s.%s' % (firstPart, packageExt, libraryExt) - - return filename - - def findLibraryFile(self, type, dir, name): - if not os.path.exists(dir): - return None - - (platform, packageExt, libraryExt) = self.getDistributePlatformInfo(type) - ext = libraryExt - - pattern = name + '\.' + ext - - for filename in os.listdir(dir): - if re.search(pattern, filename): - return dir + '/' + filename - - return None - - def getDistributePlatformInfo(self, type): - ext = None - libraryExt = None - platform = None - - if type == 'src': - ext = 'tar.gz' - platform = 'Source' - - elif type == 'rpm' or type == 'deb': - ext = type - libraryExt = 'so' - platform = self.getLinuxPlatform() - - elif type == 'win': - # get platform based on last generator used - ext = 'msi' - libraryExt = 'dll' - generator = self.getGeneratorFromConfig().cmakeName - if generator.find('Win64') != -1: - platform = 'Windows-x64' - else: - platform = 'Windows-x86' - - elif type == 'mac': - ext = "dmg" - libraryExt = 'dylib' - platform = self.getMacPackageName() - - if not platform: - raise Exception('Unable to detect distributable platform.') - - return (platform, ext, libraryExt) - - def getDistFilename(self, type): - pattern = self.getVersionForFilename() - for filename in os.listdir(self.getBinDir('Release')): - if re.search(pattern, filename): - return filename - - raise Exception('Could not find package name with pattern: ' + pattern) - - def getDebianArch(self): - if os.uname()[4][:3] == 'arm': - return 'armhf' - - # os_bits should be loaded with '32bit' or '64bit' - import platform - (os_bits, other) = platform.architecture() - - # get platform based on current platform - if os_bits == '32bit': - return 'i386' - elif os_bits == '64bit': - return 'amd64' - else: - raise Exception("unknown os bits: " + os_bits) - - def getLinuxPlatform(self): - if os.uname()[4][:3] == 'arm': - return 'Linux-armv6l' - - # os_bits should be loaded with '32bit' or '64bit' - import platform - (os_bits, other) = platform.architecture() - - # get platform based on current platform - if os_bits == '32bit': - return 'Linux-i686' - elif os_bits == '64bit': - return 'Linux-x86_64' - else: - raise Exception("unknown os bits: " + os_bits) - - def dist_usage(self): - print ('Usage: %s package [package-type]\n' - '\n' - 'Replace [package-type] with one of:\n' - ' src .tar.gz source (Posix only)\n' - ' rpm .rpm package (Red Hat)\n' - ' deb .deb package (Debian)\n' - ' win .exe installer (Windows)\n' - ' mac .dmg package (Mac OS X)\n' - '\n' - 'Example: %s package src-tgz') % (self.this_cmd, self.this_cmd) - - def about(self): - print ('Help Me script, from the Synergy project.\n' - '%s\n' - '\n' - 'For help, run: %s help') % (self.website_url, self.this_cmd) - - def try_chdir(self, dir): - global prevdir - - if dir == '': - prevdir = '' - return - - # Ensure temp build dir exists. - if not os.path.exists(dir): - print 'Creating dir: ' + dir - os.makedirs(dir) + major = int(result.group(1)) + minor = int(result.group(2)) + rev = int(result.group(3)) + + return (major, minor, rev) + + def getMacSdkDir(self): + sdkName = "macosx" + self.macSdk + + # Ideally we'll use xcrun (which is influenced by $DEVELOPER_DIR), then try a couple + # fallbacks to known paths if xcrun is not available + status, sdkPath = commands.getstatusoutput("xcrun --show-sdk-path --sdk " + sdkName) + if status == 0 and sdkPath: + return sdkPath + + developerDir = os.getenv("DEVELOPER_DIR") + if not developerDir: + developerDir = "/Applications/Xcode.app/Contents/Developer" + + sdkDirName = sdkName.replace("macosx", "MacOSX") + sdkPath = developerDir + "/Platforms/MacOSX.platform/Developer/SDKs/" + sdkDirName + ".sdk" + if os.path.exists(sdkPath): + return sdkPath + + # return os.popen('xcodebuild -version -sdk macosx' + self.macSdk + ' Path').read().strip() + return "/Developer/SDKs/" + sdkDirName + ".sdk" + + # http://tinyurl.com/cs2rxxb + def fixCmakeEclipseBug(self): + print "Fixing CMake Eclipse bugs..." + + file = open('.project', 'r+') + content = file.read() + pattern = re.compile('\s+.+', re.S) + content = pattern.sub('', content) + file.seek(0) + file.write(content) + file.truncate() + file.close() + + def persist_cmake(self): + # even though we're running `cmake --version`, we're only doing this for the 0 return + # code; we don't care about the version, since CMakeLists worrys about this for us. + err = os.system('%s --version' % self.cmake_cmd) + + if err != 0: + # if return code from cmake is not 0, then either something has + # gone terribly wrong with --version, or it genuinely doesn't exist. + print ('Could not find `%s` in system path.\n' + 'Download the latest version from:\n %s') % ( + self.cmake_cmd, self.cmake_url) + raise Exception('Cannot continue without CMake.') + else: + return self.cmake_cmd + + def persist_qt(self): + self.persist_qmake() + + def persist_qmake(self): + # cannot use subprocess on < python 2.4 + if sys.version_info < (2, 4): + return + + try: + p = subprocess.Popen( + [self.qmake_cmd, '--version'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + except: + print >> sys.stderr, 'Error: Could not find qmake.' + if sys.platform == 'win32': # windows devs usually need hints ;) + print ( + 'Suggestions:\n' + '1. Ensure that qmake.exe exists in your system path.\n' + '2. Try to download Qt 5.6\n') + raise Exception('Cannot continue without qmake.') + + stdout, stderr = p.communicate() + if p.returncode != 0: + raise Exception('Could not test for qmake: %s' % stderr) + else: + m = re.search('.*Using Qt version (\d+\.\d+\.\d+).*', stdout) + if m: + if sys.platform == 'win32': + ver = m.group(1) + if ver != self.w32_qt_version: # TODO: test properly + print >> sys.stderr, ( + 'Warning: Not using supported Qt version %s' + ' (your version is %s).' + ) % (self.w32_qt_version, ver) + else: + pass # any version should be ok for other platforms + else: + raise Exception('Could not find qmake version.') + + def ensureConfHasRun(self, target, skipConfig): + if self.hasConfRun(target): + print 'Skipping config for target: ' + target + skipConfig = True + + if not skipConfig: + self.configure(target) + + def build(self, targets=[], skipConfig=False): + + # if no mode specified, use default + if len(targets) == 0: + targets += [self.defaultTarget,] + + self.ensure_setup_latest() + + self.loadConfig() + + # allow user to skip core compile + if self.enableMakeCore: + self.makeCore(targets) + + # allow user to skip gui compile + if self.enableMakeGui: + self.makeGui(targets) + + def loadConfig(self): + config = self.getConfig() + + if config.has_option("hm", "macSdk"): + self.macSdk = config.get("hm", "macSdk") + + if config.has_option("hm", "macDeploy"): + self.macDeploy = config.get("hm", "macDeploy") + + if config.has_option("hm", "macIdentity"): + self.macIdentity = config.get("hm", "macIdentity") + + def makeCore(self, targets): + + generator = self.getGeneratorFromConfig().cmakeName + + if self.macSdk: + os.environ["MACOSX_DEPLOYMENT_TARGET"] = self.macSdk + + if generator.find('Unix Makefiles') != -1: + for target in targets: + self.runBuildCommand(self.make_cmd, target) + else: + for target in targets: + if generator.startswith('Visual Studio'): + self.run_vcbuild(generator, target, self.sln_filepath()) + elif generator == 'Xcode': + cmd = self.xcodebuild_cmd + ' -configuration ' + target.capitalize() + self.runBuildCommand(cmd, target) + else: + raise Exception('Build command not supported with generator: ' + generator) + + def makeGui(self, targets, args=""): + for target in targets: + + if sys.platform == 'win32': + + gui_make_cmd = self.w32_make_cmd + ' ' + target + args + print 'Make GUI command: ' + gui_make_cmd + + self.try_chdir(self.gui_dir) + err = os.system(gui_make_cmd) + self.restore_chdir() + + if err != 0: + raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) + + elif sys.platform in ['linux2', 'sunos5', 'freebsd7', 'darwin']: + + gui_make_cmd = self.make_cmd + " -w" + args + print 'Make GUI command: ' + gui_make_cmd + + # start with a clean app bundle + targetDir = self.getGenerator().getBinDir(target) + bundleTargetDir = targetDir + '/Synergy.app' + if os.path.exists(bundleTargetDir): + shutil.rmtree(bundleTargetDir) + + binDir = self.getGenerator().binDir + bundleTempDir = binDir + '/Synergy.app' + if os.path.exists(bundleTempDir): + shutil.rmtree(bundleTempDir) + + self.try_chdir(self.gui_dir) + err = os.system(gui_make_cmd) + self.restore_chdir() + + if err != 0: + raise Exception(gui_make_cmd + ' failed with error: ' + str(err)) + + if sys.platform == 'darwin' and not "clean" in args: + self.macPostGuiMake(target) + + self.fixQtFrameworksLayout(target) + else: + raise Exception('Unsupported platform: ' + sys.platform) + + def macPostGuiMake(self, target): + bundle = 'Synergy.app' + binDir = self.getGenerator().binDir + targetDir = self.getGenerator().getBinDir(target) + bundleTempDir = binDir + '/' + bundle + bundleTargetDir = targetDir + '/' + bundle + + if os.path.exists(bundleTempDir): + shutil.move(bundleTempDir, bundleTargetDir) + + if self.enableMakeCore: + # copy core binaries into the bundle, since the gui + # now looks for the binaries in the current app dir. + + bundleBinDir = bundleTargetDir + "/Contents/MacOS/" + shutil.copy(targetDir + "/synergyc", bundleBinDir) + shutil.copy(targetDir + "/synergys", bundleBinDir) + shutil.copy(targetDir + "/syntool", bundleBinDir) + + self.loadConfig() + if not self.macIdentity: + raise Exception("run config with --mac-identity") + + if self.enableMakeGui: + # use qt to copy libs to bundle so no dependencies are needed. do not create a + # dmg at this point, since we need to sign it first, and then create our own + # after signing (so that qt does not affect the signed app bundle). + bin = "macdeployqt Synergy.app -verbose=2" + self.try_chdir(targetDir) + err = os.system(bin) + self.restore_chdir() + print bundleTargetDir + if err != 0: + raise Exception(bin + " failed with error: " + str(err)) + + frameworkRootDir = commands.getoutput("qmake -query QT_INSTALL_LIBS") + + target = bundleTargetDir + "/Contents/Frameworks" + + # copy the missing Info.plist files for the frameworks. + for root, dirs, files in os.walk(target): + for dir in dirs: + if dir.startswith("Qt"): + shutil.copy( + frameworkRootDir + "/" + dir + "/Contents/Info.plist", + target + "/" + dir + "/Resources/") + + def symlink(self, source, target): + if not os.path.exists(target): + os.symlink(source, target) + + def move(self, source, target): + if os.path.exists(source): + shutil.move(source, target) + + def fixQtFrameworksLayout(self, target): + # reorganize Qt frameworks layout on Mac 10.9.5 or later + # http://goo.gl/BFnQ8l + # QtCore example: + # QtCore.framework/ + # QtCore -> Versions/Current/QtCore + # Resources -> Versions/Current/Resources + # Versions/ + # Current -> 5 + # 5/ + # QtCore + # Resources/ + # Info.plist + targetDir = self.getGenerator().getBinDir(target) + + target = targetDir + "/Synergy.app/Contents/Frameworks" + (major, minor) = self.getMacVersion() + if major == 10: + if minor >= 9: + for root, dirs, files in os.walk(target): + for dir in dirs: + if dir.startswith("Qt"): + self.try_chdir(target + "/" + dir +"/Versions") + self.symlink("5", "Current") + self.move("../Resources", "5") + self.restore_chdir() + + self.try_chdir(target + "/" + dir) + dot = dir.find('.') + frameworkName = dir[:dot] + self.symlink("Versions/Current/" + frameworkName, frameworkName) + self.symlink("Versions/Current/Resources", "Resources") + self.restore_chdir() + + def signmac(self): + self.loadConfig() + if not self.macIdentity: + raise Exception("run config with --mac-identity") + + self.try_chdir("bin/Release/") + err = os.system( + 'codesign --deep -fs "' + self.macIdentity + '" Synergy.app') + self.restore_chdir() + + if err != 0: + raise Exception("codesign failed with error: " + str(err)) + + def signwin(self, pfx, pwdFile, dist): + generator = self.getGeneratorFromConfig().cmakeName + if not generator.startswith('Visual Studio'): + raise Exception('only windows is supported') + + f = open(pwdFile) + lines = f.readlines() + f.close() + pwd = lines[0] + + if (dist): + self.signFile(pfx, pwd, 'bin/Release', self.getDistFilename('win')) + else: + self.signFile(pfx, pwd, 'bin/Release', 'synergy.exe') + self.signFile(pfx, pwd, 'bin/Release', 'synergyc.exe') + self.signFile(pfx, pwd, 'bin/Release', 'synergys.exe') + self.signFile(pfx, pwd, 'bin/Release', 'synergyd.exe') + self.signFile(pfx, pwd, 'bin/Release', 'syntool.exe') + self.signFile(pfx, pwd, 'bin/Release', 'synwinhk.dll') + + def signFile(self, pfx, pwd, dir, file): + self.try_chdir(dir) + err = os.system( + 'signtool sign' + ' /f ' + pfx + + ' /p ' + pwd + + ' /t http://timestamp.verisign.com/scripts/timstamp.dll ' + + file) + self.restore_chdir() + + if err != 0: + raise Exception("signtool failed with error: " + str(err)) + + def runBuildCommand(self, cmd, target): + + self.try_chdir(self.getBuildDir(target)) + err = os.system(cmd) + self.restore_chdir() + + if err != 0: + raise Exception(cmd + ' failed: ' + str(err)) + + def clean(self, targets=[]): + + # if no mode specified, use default + if len(targets) == 0: + targets += [self.defaultTarget,] + + # allow user to skip core clean + if self.enableMakeCore: + self.cleanCore(targets) + + # allow user to skip qui clean + if self.enableMakeGui: + self.cleanGui(targets) + + def cleanCore(self, targets): + generator = self.getGeneratorFromConfig().cmakeName + + if generator.startswith('Visual Studio'): + # special case for version 10 and above, use new /target:clean + if generator.startswith('Visual Studio 10') or generator.startswith('Visual Studio 14'): + for target in targets: + self.run_vcbuild(generator, target, self.sln_filepath(), '/target:clean') + + # any other version of visual studio, use /clean + elif generator.startswith('Visual Studio'): + for target in targets: + self.run_vcbuild(generator, target, self.sln_filepath(), '/clean') + + else: + cmd = '' + if generator == "Unix Makefiles": + print 'Cleaning with GNU Make...' + cmd = self.make_cmd + elif generator == 'Xcode': + print 'Cleaning with Xcode...' + cmd = self.xcodebuild_cmd + else: + raise Exception('Not supported with generator: ' + generator) + + for target in targets: + self.try_chdir(self.getBuildDir(target)) + err = os.system(cmd + ' clean') + self.restore_chdir() + + if err != 0: + raise Exception('Clean failed: ' + str(err)) + + def cleanGui(self, targets): + self.makeGui(targets, " clean") + + def open(self): + generator = self.getGeneratorFromConfig().cmakeName + if generator.startswith('Visual Studio'): + print 'Opening with %s...' % generator + self.open_internal(self.sln_filepath()) + + elif generator.startswith('Xcode'): + print 'Opening with %s...' % generator + self.open_internal(self.xcodeproj_filepath(), 'open') + + else: + raise Exception('Not supported with generator: ' + generator) + + def update(self): + print "Running Subversion update..." + err = os.system('svn update') + if err != 0: + raise Exception('Could not update from repository with error code code: ' + str(err)) + + def revision(self): + print self.find_revision() + + def find_revision(self): + return self.getGitRevision() + + def getGitRevision(self): + if sys.version_info < (2, 4): + raise Exception("Python 2.4 or greater required.") + + p = subprocess.Popen( + ["git", "log", "--pretty=format:%h", "-n", "1"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + stdout, stderr = p.communicate() + + if p.returncode != 0: + raise Exception('Could not get revision, git error: ' + str(p.returncode)) + + return stdout.strip() + + def getGitBranchName(self): + if sys.version_info < (2, 4): + raise Exception("Python 2.4 or greater required.") + + p = subprocess.Popen( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + stdout, stderr = p.communicate() + + if p.returncode != 0: + raise Exception('Could not get branch name, git error: ' + str(p.returncode)) + + result = stdout.strip() + + # sometimes, git will prepend "heads/" infront of the branch name, + # remove this as it's not useful to us and causes ftp issues. + result = re.sub("heads/", "", result) + + return result + + def find_revision_svn(self): + if sys.version_info < (2, 4): + stdout = commands.getoutput('svn info') + else: + p = subprocess.Popen(['svn', 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + + if p.returncode != 0: + raise Exception('Could not get revision - svn info failed with code: ' + str(p.returncode)) + + m = re.search('.*Revision: (\d+).*', stdout) + if not m: + raise Exception('Could not find revision number in svn info output.') + + return m.group(1) + + def kill(self): + if sys.platform == 'win32': + return os.system('taskkill /F /FI "IMAGENAME eq synergy*"') + else: + raise Exception('Not implemented for platform: ' + sys.platform) + + def doxygen(self): + self.enableMakeGui = False + + # The conf generates doc/doxygen.cfg from cmake/doxygen.cfg.in + self.configure(self.defaultTarget, '-DCONF_DOXYGEN:BOOL=TRUE') + + err = os.system('doxygen %s/%s' % (self.doc_dir, self.doxygen_filename)) + + if err != 0: + raise Exception('doxygen failed with error code: ' + str(err)) + + def dist(self, type, vcRedistDir, qtDir): + + # Package is supported by default. + package_unsupported = False + unixTarget = self.defaultTarget + + if type == '' or type == None: + self.dist_usage() + return + + moveExt = '' + + if type == 'src': + self.distSrc() + + elif type == 'rpm': + if sys.platform == 'linux2': + self.distRpm() + else: + package_unsupported = True + + elif type == 'deb': + if sys.platform == 'linux2': + self.distDeb() + else: + package_unsupported = True + + elif type == 'win': + if sys.platform == 'win32': + #self.distNsis(vcRedistDir, qtDir) + self.distWix() + else: + package_unsupported = True + + elif type == 'mac': + if sys.platform == 'darwin': + self.distMac() + else: + package_unsupported = True + + else: + raise Exception('Package type not supported: ' + type) + + if moveExt != '': + self.unixMove( + self.getGenerator().buildDir + '/release/*.' + moveExt, + self.getGenerator().binDir) + + if package_unsupported: + raise Exception( + ("Package type, '%s' is not supported for platform, '%s'") + % (type, sys.platform)) + + def distRpm(self): + rpmDir = self.getGenerator().buildDir + '/rpm' + if os.path.exists(rpmDir): + shutil.rmtree(rpmDir) + + os.makedirs(rpmDir) + + templateFile = open(self.cmake_dir + '/synergy.spec.in') + template = templateFile.read() + + template = template.replace('${in:version}', self.getVersionNumber()) + + specPath = rpmDir + '/synergy.spec' + + specFile = open(specPath, 'w') + specFile.write(template) + specFile.close() + + target = '../../bin/synergy-%s-%s.rpm' % ( + self.getVersionForFilename(), self.getLinuxPlatform()) + + try: + self.try_chdir(rpmDir) + cmd = 'rpmbuild -bb --define "_topdir `pwd`" synergy.spec' + print "Command: " + cmd + err = os.system(cmd) + if err != 0: + raise Exception('rpmbuild failed: ' + str(err)) + + self.unixMove('RPMS/*/*.rpm', target) + + cmd = 'rpmlint ' + target + print "Command: " + cmd + err = os.system(cmd) + if err != 0: + raise Exception('rpmlint failed: ' + str(err)) + + finally: + self.restore_chdir() + + def distDeb(self): + buildDir = self.getGenerator().buildDir + binDir = self.getGenerator().binDir + resDir = self.cmake_dir + + package = '%s-%s-%s' % ( + self.project, + self.getVersionForFilename(), + self.getLinuxPlatform()) + + debDir = '%s/deb' % buildDir + if os.path.exists(debDir): + shutil.rmtree(debDir) + + metaDir = '%s/%s/DEBIAN' % (debDir, package) + os.makedirs(metaDir) + + templateFile = open(resDir + '/deb/control.in') + template = templateFile.read() + + template = template.replace('${in:version}', + self.getVersionNumber()) + + template = template.replace('${in:arch}', + self.getDebianArch()) + + controlPath = '%s/control' % metaDir + + controlFile = open(controlPath, 'w') + controlFile.write(template) + controlFile.close() + + targetBin = '%s/%s/usr/bin' % (debDir, package) + targetShare = '%s/%s/usr/share' % (debDir, package) + targetApplications = "%s/applications" % targetShare + targetIcons = "%s/icons" % targetShare + targetDocs = "%s/doc/%s" % (targetShare, self.project) + + os.makedirs(targetBin) + os.makedirs(targetApplications) + os.makedirs(targetIcons) + os.makedirs(targetDocs) + + for root, dirs, files in os.walk(debDir): + for d in dirs: + os.chmod(os.path.join(root, d), 0o0755) + + binFiles = ['synergy', 'synergyc', 'synergys', 'synergyd', 'syntool'] + for f in binFiles: + shutil.copy("%s/%s" % (binDir, f), targetBin) + target = "%s/%s" % (targetBin, f) + os.chmod(target, 0o0755) + err = os.system("strip " + target) + if err != 0: + raise Exception('strip failed: ' + str(err)) + + shutil.copy("%s/synergy.desktop" % resDir, targetApplications) + shutil.copy("%s/synergy.ico" % resDir, targetIcons) + + docTarget = "%s/doc/%s" % (targetShare, self.project) + + copyrightPath = "%s/deb/copyright" % resDir + shutil.copy(copyrightPath, docTarget) + + shutil.copy("%s/deb/changelog" % resDir, docTarget) + os.system("gzip -9 %s/changelog" % docTarget) + if err != 0: + raise Exception('gzip failed: ' + str(err)) + + for root, dirs, files in os.walk(targetShare): + for f in files: + os.chmod(os.path.join(root, f), 0o0644) + + target = '../../bin/%s.deb' % package + + try: + self.try_chdir(debDir) + + # TODO: consider dpkg-buildpackage (higher level tool) + cmd = 'fakeroot dpkg-deb --build %s' % package + print "Command: " + cmd + err = os.system(cmd) + if err != 0: + raise Exception('dpkg-deb failed: ' + str(err)) + + cmd = 'lintian %s.deb' % package + print "Command: " + cmd + err = os.system(cmd) + if err != 0: + raise Exception('lintian failed: ' + str(err)) + + self.unixMove('*.deb', target) + finally: + self.restore_chdir() + + def distSrc(self): + name = '%s-%s-%s' % ( + self.project, + self.getVersionForFilename(), + 'Source') + + exportPath = self.getGenerator().buildDir + '/' + name + + if os.path.exists(exportPath): + print "Removing existing export..." + shutil.rmtree(exportPath) + + os.mkdir(exportPath) + + cmd = "git archive %s | tar -x -C %s" % ( + self.getGitBranchName(), exportPath) + + print 'Exporting repository to: ' + exportPath + err = os.system(cmd) + if err != 0: + raise Exception('Repository export failed: ' + str(err)) + + packagePath = '../' + self.getGenerator().binDir + '/' + name + '.tar.gz' + + try: + self.try_chdir(self.getGenerator().buildDir) + print 'Packaging to: ' + packagePath + err = os.system('tar cfvz ' + packagePath + ' ' + name) + if err != 0: + raise Exception('Package failed: ' + str(err)) + finally: + self.restore_chdir() + + def unixMove(self, source, dest): + print 'Moving ' + source + ' to ' + dest + err = os.system('mv ' + source + ' ' + dest) + if err != 0: + raise Exception('Package failed: ' + str(err)) + + def distMac(self): + self.loadConfig() + binDir = self.getGenerator().getBinDir('Release') + name = "Synergy" + dist = binDir + "/" + name + + # ensure dist dir is clean + if os.path.exists(dist): + shutil.rmtree(dist) + + os.makedirs(dist) + shutil.move(binDir + "/" + name + ".app", dist + "/" + name + ".app") + + self.try_chdir(dist) + err = os.system("ln -s /Applications") + self.restore_chdir() + + fileName = "%s-%s-%s.dmg" % ( + self.project, + self.getVersionForFilename(), + self.getMacPackageName()) + + cmd = "hdiutil create " + fileName + " -srcfolder ./" + name + "/ -ov" + + self.try_chdir(binDir) + err = os.system(cmd) + self.restore_chdir() + + def distWix(self): + generator = self.getGeneratorFromConfig().cmakeName + + arch = 'x86' + if generator.endswith('Win64'): + arch = 'x64' + + version = self.getVersionNumber() + args = "/p:DefineConstants=\"Version=%s\"" % version + + self.run_vcbuild( + generator, 'release', 'synergy.sln', args, + 'src/setup/win32/', 'x86') + + filename = "%s-%s-Windows-%s.msi" % ( + self.project, + self.getVersionForFilename(), + arch) + + old = "bin/Release/synergy.msi" + new = "bin/Release/%s" % (filename) + + try: + os.remove(new) + except OSError: + pass + + os.rename(old, new) + + def distNsis(self, vcRedistDir, qtDir): + + if vcRedistDir == '': + raise Exception( + 'VC++ redist dir path not specified (--vcredist-dir).') + + if qtDir == '': + raise Exception( + 'QT SDK dir path not specified (--qt-dir).') + + generator = self.getGeneratorFromConfig().cmakeName + + arch = 'x86' + installDirVar = '$PROGRAMFILES32' + + if generator.endswith('Win64'): + arch = 'x64' + installDirVar = '$PROGRAMFILES64' + + templateFile = open(self.cmake_dir + '\Installer.nsi.in') + template = templateFile.read() + + template = template.replace('${in:version}', self.getVersionNumber()) + template = template.replace('${in:arch}', arch) + template = template.replace('${in:vcRedistDir}', vcRedistDir) + template = template.replace('${in:qtDir}', qtDir) + template = template.replace('${in:installDirVar}', installDirVar) + + nsiPath = self.getGenerator().buildDir + '\Installer.nsi' + nsiFile = open(nsiPath, 'w') + nsiFile.write(template) + nsiFile.close() + + command = 'makensis ' + nsiPath + print 'NSIS command: ' + command + err = os.system(command) + if err != 0: + raise Exception('Package failed: ' + str(err)) + + def getVersionNumber(self): + cmakeFile = open('CMakeLists.txt') + cmake = cmakeFile.read() + + majorRe = re.search('VERSION_MAJOR (\d+)', cmake) + major = majorRe.group(1) + + minorRe = re.search('VERSION_MINOR (\d+)', cmake) + minor = minorRe.group(1) + + revRe = re.search('VERSION_REV (\d+)', cmake) + rev = revRe.group(1) + + return "%s.%s.%s" % (major, minor, rev) + + def getVersionStage(self): + cmakeFile = open('CMakeLists.txt') + cmake = cmakeFile.read() + + stageRe = re.search('VERSION_STAGE (\w+)', cmake) + return stageRe.group(1) + + def getVersionForFilename(self): + versionStage = self.getVersionStage() + gitBranch = self.getGitBranchName() + gitRevision = self.getGitRevision() + return "%s-%s-%s" % (gitBranch, versionStage, gitRevision) + + def distftp(self, type, ftp): + if not type: + raise Exception('Platform type not specified.') + + self.loadConfig() + + binDir = self.getGenerator().getBinDir('Release') + + filename = self.getDistFilename(type) + packageSource = binDir + '/' + filename + packageTarget = filename + ftp.upload(packageSource, packageTarget) + + def getLibraryDistFilename(self, type, dir, name): + (platform, packageExt, libraryExt) = self.getDistributePlatformInfo(type) + firstPart = '%s-%s-%s' % (name, self.getVersionForFilename(), platform) + + filename = '%s.%s' % (firstPart, libraryExt) + if type == 'rpm' or type == 'deb': + # linux is a bit special, include dist type (deb/rpm in filename) + filename = '%s-%s.%s' % (firstPart, packageExt, libraryExt) + + return filename + + def findLibraryFile(self, type, dir, name): + if not os.path.exists(dir): + return None + + (platform, packageExt, libraryExt) = self.getDistributePlatformInfo(type) + ext = libraryExt + + pattern = name + '\.' + ext + + for filename in os.listdir(dir): + if re.search(pattern, filename): + return dir + '/' + filename + + return None + + def getDistributePlatformInfo(self, type): + ext = None + libraryExt = None + platform = None + + if type == 'src': + ext = 'tar.gz' + platform = 'Source' + + elif type == 'rpm' or type == 'deb': + ext = type + libraryExt = 'so' + platform = self.getLinuxPlatform() + + elif type == 'win': + # get platform based on last generator used + ext = 'msi' + libraryExt = 'dll' + generator = self.getGeneratorFromConfig().cmakeName + if generator.find('Win64') != -1: + platform = 'Windows-x64' + else: + platform = 'Windows-x86' + + elif type == 'mac': + ext = "dmg" + libraryExt = 'dylib' + platform = self.getMacPackageName() + + if not platform: + raise Exception('Unable to detect distributable platform.') + + return (platform, ext, libraryExt) + + def getDistFilename(self, type): + pattern = self.getVersionForFilename() + for filename in os.listdir(self.getBinDir('Release')): + if re.search(pattern, filename): + return filename + + raise Exception('Could not find package name with pattern: ' + pattern) + + def getDebianArch(self): + if os.uname()[4][:3] == 'arm': + return 'armhf' + + # os_bits should be loaded with '32bit' or '64bit' + import platform + (os_bits, other) = platform.architecture() + + # get platform based on current platform + if os_bits == '32bit': + return 'i386' + elif os_bits == '64bit': + return 'amd64' + else: + raise Exception("unknown os bits: " + os_bits) + + def getLinuxPlatform(self): + if os.uname()[4][:3] == 'arm': + return 'Linux-armv6l' + + # os_bits should be loaded with '32bit' or '64bit' + import platform + (os_bits, other) = platform.architecture() + + # get platform based on current platform + if os_bits == '32bit': + return 'Linux-i686' + elif os_bits == '64bit': + return 'Linux-x86_64' + else: + raise Exception("unknown os bits: " + os_bits) + + def dist_usage(self): + print ('Usage: %s package [package-type]\n' + '\n' + 'Replace [package-type] with one of:\n' + ' src .tar.gz source (Posix only)\n' + ' rpm .rpm package (Red Hat)\n' + ' deb .deb package (Debian)\n' + ' win .exe installer (Windows)\n' + ' mac .dmg package (Mac OS X)\n' + '\n' + 'Example: %s package src-tgz') % (self.this_cmd, self.this_cmd) + + def about(self): + print ('Help Me script, from the Synergy project.\n' + '%s\n' + '\n' + 'For help, run: %s help') % (self.website_url, self.this_cmd) + + def try_chdir(self, dir): + global prevdir + + if dir == '': + prevdir = '' + return + + # Ensure temp build dir exists. + if not os.path.exists(dir): + print 'Creating dir: ' + dir + os.makedirs(dir) - prevdir = os.path.abspath(os.curdir) + prevdir = os.path.abspath(os.curdir) - # It will exist by this point, so it's safe to chdir. - print 'Entering dir: ' + dir - os.chdir(dir) + # It will exist by this point, so it's safe to chdir. + print 'Entering dir: ' + dir + os.chdir(dir) - def restore_chdir(self): - global prevdir - if prevdir == '': - return - print 'Going back to: ' + prevdir - os.chdir(prevdir) + def restore_chdir(self): + global prevdir + if prevdir == '': + return + print 'Going back to: ' + prevdir + os.chdir(prevdir) - def open_internal(self, project_filename, application = ''): + def open_internal(self, project_filename, application = ''): - if not os.path.exists(project_filename): - raise Exception('Project file (%s) not found, run hm conf first.' % project_filename) - else: - path = project_filename - - if application != '': - path = application + ' ' + path - - err = os.system(path) - if err != 0: - raise Exception('Could not open project with error code code: ' + str(err)) + if not os.path.exists(project_filename): + raise Exception('Project file (%s) not found, run hm conf first.' % project_filename) + else: + path = project_filename + + if application != '': + path = application + ' ' + path + + err = os.system(path) + if err != 0: + raise Exception('Could not open project with error code code: ' + str(err)) - def setup(self, target=''): - print "Running setup..." + def setup(self, target=''): + print "Running setup..." - oldGenerator = self.findGeneratorFromConfig() - if not oldGenerator == None: - for target in ['debug', 'release']: - buildDir = oldGenerator.getBuildDir(target) + oldGenerator = self.findGeneratorFromConfig() + if not oldGenerator == None: + for target in ['debug', 'release']: + buildDir = oldGenerator.getBuildDir(target) - cmakeCacheFilename = 'CMakeCache.txt' - if buildDir != '': - cmakeCacheFilename = buildDir + '/' + cmakeCacheFilename + cmakeCacheFilename = 'CMakeCache.txt' + if buildDir != '': + cmakeCacheFilename = buildDir + '/' + cmakeCacheFilename - if os.path.exists(cmakeCacheFilename): - print "Removing %s, since generator changed." % cmakeCacheFilename - os.remove(cmakeCacheFilename) + if os.path.exists(cmakeCacheFilename): + print "Removing %s, since generator changed." % cmakeCacheFilename + os.remove(cmakeCacheFilename) - # always either get generator from args, or prompt user when - # running setup - generator = self.get_generator_from_prompt() + # always either get generator from args, or prompt user when + # running setup + generator = self.get_generator_from_prompt() - config = self.getConfig() - config.set('hm', 'setup_version', self.setup_version) - - # store the generator so we don't need to ask again - config.set('cmake', 'generator', generator) + config = self.getConfig() + config.set('hm', 'setup_version', self.setup_version) + + # store the generator so we don't need to ask again + config.set('cmake', 'generator', generator) - self.write_config(config) + self.write_config(config) - # for all targets, set conf not run - self.setConfRun('all', False) - self.setConfRun('debug', False) - self.setConfRun('release', False) + # for all targets, set conf not run + self.setConfRun('all', False) + self.setConfRun('debug', False) + self.setConfRun('release', False) - print "Setup complete." + print "Setup complete." - def getConfig(self): - if os.path.exists(self.configFilename): - config = ConfigParser.ConfigParser() - config.read(self.configFilename) - else: - config = ConfigParser.ConfigParser() + def getConfig(self): + if os.path.exists(self.configFilename): + config = ConfigParser.ConfigParser() + config.read(self.configFilename) + else: + config = ConfigParser.ConfigParser() - if not config.has_section('hm'): - config.add_section('hm') + if not config.has_section('hm'): + config.add_section('hm') - if not config.has_section('cmake'): - config.add_section('cmake') + if not config.has_section('cmake'): + config.add_section('cmake') - return config + return config - def write_config(self, config, target=''): - if not os.path.isdir(self.configDir): - os.mkdir(self.configDir) - configfile = open(self.configFilename, 'wb') - config.write(configfile) + def write_config(self, config, target=''): + if not os.path.isdir(self.configDir): + os.mkdir(self.configDir) + configfile = open(self.configFilename, 'wb') + config.write(configfile) - def getGeneratorFromConfig(self): - generator = self.findGeneratorFromConfig() - if generator: - return generator - - raise Exception("Could not find generator: " + name) + def getGeneratorFromConfig(self): + generator = self.findGeneratorFromConfig() + if generator: + return generator + + raise Exception("Could not find generator: " + name) - def findGeneratorFromConfig(self): - config = ConfigParser.RawConfigParser() - config.read(self.configFilename) - - if not config.has_section('cmake'): - return None - - name = config.get('cmake', 'generator') + def findGeneratorFromConfig(self): + config = ConfigParser.RawConfigParser() + config.read(self.configFilename) + + if not config.has_section('cmake'): + return None + + name = config.get('cmake', 'generator') - generators = self.get_generators() - keys = generators.keys() - keys.sort() - for k in keys: - if generators[k].cmakeName == name: - return generators[k] - - return None + generators = self.get_generators() + keys = generators.keys() + keys.sort() + for k in keys: + if generators[k].cmakeName == name: + return generators[k] + + return None - def min_setup_version(self, version): - if os.path.exists(self.configFilename): - config = ConfigParser.RawConfigParser() - config.read(self.configFilename) + def min_setup_version(self, version): + if os.path.exists(self.configFilename): + config = ConfigParser.RawConfigParser() + config.read(self.configFilename) - try: - return config.getint('hm', 'setup_version') >= version - except: - return False - else: - return False + try: + return config.getint('hm', 'setup_version') >= version + except: + return False + else: + return False - def hasConfRun(self, target): - if self.min_setup_version(2): - config = ConfigParser.RawConfigParser() - config.read(self.configFilename) - try: - return config.getboolean('hm', 'conf_done_' + target) - except: - return False - else: - return False + def hasConfRun(self, target): + if self.min_setup_version(2): + config = ConfigParser.RawConfigParser() + config.read(self.configFilename) + try: + return config.getboolean('hm', 'conf_done_' + target) + except: + return False + else: + return False - def setConfRun(self, target, hasRun=True): - if self.min_setup_version(3): - config = ConfigParser.RawConfigParser() - config.read(self.configFilename) - config.set('hm', 'conf_done_' + target, hasRun) - self.write_config(config) - else: - raise Exception("User does not have correct setup version.") + def setConfRun(self, target, hasRun=True): + if self.min_setup_version(3): + config = ConfigParser.RawConfigParser() + config.read(self.configFilename) + config.set('hm', 'conf_done_' + target, hasRun) + self.write_config(config) + else: + raise Exception("User does not have correct setup version.") - def get_generators(self): - if sys.platform == 'win32': - return self.win32_generators - elif sys.platform in ['linux2', 'sunos5', 'freebsd7', 'aix5']: - return self.unix_generators - elif sys.platform == 'darwin': - return self.darwin_generators - else: - raise Exception('Unsupported platform: ' + sys.platform) - - def get_generator_from_prompt(self): - return self.getGenerator().cmakeName + def get_generators(self): + if sys.platform == 'win32': + return self.win32_generators + elif sys.platform in ['linux2', 'sunos5', 'freebsd7', 'aix5']: + return self.unix_generators + elif sys.platform == 'darwin': + return self.darwin_generators + else: + raise Exception('Unsupported platform: ' + sys.platform) + + def get_generator_from_prompt(self): + return self.getGenerator().cmakeName - def getGenerator(self): - generators = self.get_generators() - if len(generators.keys()) == 1: - return generators[generators.keys()[0]] - - # if user has specified a generator as an argument - if self.generator_id: - return generators[int(self.generator_id)] + def getGenerator(self): + generators = self.get_generators() + if len(generators.keys()) == 1: + return generators[generators.keys()[0]] + + # if user has specified a generator as an argument + if self.generator_id: + return generators[int(self.generator_id)] - conf = self.findGeneratorFromConfig() - if conf: - return conf - - raise Exception( - 'Generator not specified, use -g arg ' + - '(use `hm genlist` for a list of generators).') + conf = self.findGeneratorFromConfig() + if conf: + return conf + + raise Exception( + 'Generator not specified, use -g arg ' + + '(use `hm genlist` for a list of generators).') - def setup_generator_prompt(self, generators): + def setup_generator_prompt(self, generators): - if self.no_prompts: - raise Exception('User prompting is disabled.') - - prompt = 'Enter a number:' - print prompt, - - generator_id = raw_input() - - if generator_id in generators: - print 'Selected generator:', generators[generator_id] - else: - print 'Invalid number, try again.' - self.setup_generator_prompt(generators) + if self.no_prompts: + raise Exception('User prompting is disabled.') + + prompt = 'Enter a number:' + print prompt, + + generator_id = raw_input() + + if generator_id in generators: + print 'Selected generator:', generators[generator_id] + else: + print 'Invalid number, try again.' + self.setup_generator_prompt(generators) - return generators[generator_id] + return generators[generator_id] - def get_vcvarsall(self, generator): - import platform, _winreg - - # os_bits should be loaded with '32bit' or '64bit' - (os_bits, other) = platform.architecture() - - # visual studio is a 32-bit app, so when we're on 64-bit, we need to check the WoW dungeon - if os_bits == '64bit': - key_name = r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7' - else: - key_name = r'SOFTWARE\Microsoft\VisualStudio\SxS\VC7' - - try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name) - except: - raise Exception('Unable to open Visual Studio registry key. Application may not be installed.') - - if generator.startswith('Visual Studio 8'): - value,type = _winreg.QueryValueEx(key, '8.0') - elif generator.startswith('Visual Studio 9'): - value,type = _winreg.QueryValueEx(key, '9.0') - elif generator.startswith('Visual Studio 10'): - value,type = _winreg.QueryValueEx(key, '10.0') - elif generator.startswith('Visual Studio 14'): - value,type = _winreg.QueryValueEx(key, '14.0') - else: - raise Exception('Cannot determine vcvarsall.bat location for: ' + generator) - - # not sure why, but the value on 64-bit differs slightly to the original - if os_bits == '64bit': - path = value + r'vc\vcvarsall.bat' - else: - path = value + r'vcvarsall.bat' - - if not os.path.exists(path): - raise Exception("'%s' not found." % path) - - return path + def get_vcvarsall(self, generator): + import platform, _winreg + + # os_bits should be loaded with '32bit' or '64bit' + (os_bits, other) = platform.architecture() + + # visual studio is a 32-bit app, so when we're on 64-bit, we need to check the WoW dungeon + if os_bits == '64bit': + key_name = r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\SxS\VS7' + else: + key_name = r'SOFTWARE\Microsoft\VisualStudio\SxS\VC7' + + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name) + except: + raise Exception('Unable to open Visual Studio registry key. Application may not be installed.') + + if generator.startswith('Visual Studio 8'): + value,type = _winreg.QueryValueEx(key, '8.0') + elif generator.startswith('Visual Studio 9'): + value,type = _winreg.QueryValueEx(key, '9.0') + elif generator.startswith('Visual Studio 10'): + value,type = _winreg.QueryValueEx(key, '10.0') + elif generator.startswith('Visual Studio 14'): + value,type = _winreg.QueryValueEx(key, '14.0') + else: + raise Exception('Cannot determine vcvarsall.bat location for: ' + generator) + + # not sure why, but the value on 64-bit differs slightly to the original + if os_bits == '64bit': + path = value + r'vc\vcvarsall.bat' + else: + path = value + r'vcvarsall.bat' + + if not os.path.exists(path): + raise Exception("'%s' not found." % path) + + return path - def run_vcbuild(self, generator, mode, solution, args='', dir='', config32='Win32'): - import platform - - # os_bits should be loaded with '32bit' or '64bit' - (os_bits, other) = platform.architecture() - # Now we choose the parameters bases on OS 32/64 and our target 32/64 - # http://msdn.microsoft.com/en-us/library/x4d2c09s%28VS.80%29.aspx - - # valid options are only: ia64 amd64 x86_amd64 x86_ia64 - # but calling vcvarsall.bat does not garantee that it will work - # ret code from vcvarsall.bat is always 0 so the only way of knowing that I worked is by analysing the text output - # ms bugg: install VS9, FeaturePack, VS9SP1 and you'll obtain a vcvarsall.bat that fails. - if generator.find('Win64') != -1: - # target = 64bit - if os_bits == '32bit': - vcvars_platform = 'x86_amd64' # 32bit OS building 64bit app - else: - vcvars_platform = 'amd64' # 64bit OS building 64bit app - config_platform = 'x64' - else: # target = 32bit - vcvars_platform = 'x86' # 32/64bit OS building 32bit app - config_platform = config32 - - if mode == 'release': - config = 'Release' - else: - config = 'Debug' - - if generator.startswith('Visual Studio 10') or generator.startswith('Visual Studio 14'): - cmd = ('@echo off\n' - 'call "%s" %s \n' - 'cd "%s"\n' - 'msbuild /nologo %s /p:Configuration="%s" /p:Platform="%s" "%s"' - ) % (self.get_vcvarsall(generator), vcvars_platform, dir, args, config, config_platform, solution) - else: - config = config + '|' + config_platform - cmd = ('@echo off\n' - 'call "%s" %s \n' - 'cd "%s"\n' - 'vcbuild /nologo %s "%s" "%s"' - ) % (self.get_vcvarsall(generator), vcvars_platform, dir, args, solution, config) - - # Generate a batch file, since we can't use environment variables directly. - temp_bat = self.getBuildDir() + r'\vcbuild.bat' - file = open(temp_bat, 'w') - file.write(cmd) - file.close() + def run_vcbuild(self, generator, mode, solution, args='', dir='', config32='Win32'): + import platform + + # os_bits should be loaded with '32bit' or '64bit' + (os_bits, other) = platform.architecture() + # Now we choose the parameters bases on OS 32/64 and our target 32/64 + # http://msdn.microsoft.com/en-us/library/x4d2c09s%28VS.80%29.aspx + + # valid options are only: ia64 amd64 x86_amd64 x86_ia64 + # but calling vcvarsall.bat does not garantee that it will work + # ret code from vcvarsall.bat is always 0 so the only way of knowing that I worked is by analysing the text output + # ms bugg: install VS9, FeaturePack, VS9SP1 and you'll obtain a vcvarsall.bat that fails. + if generator.find('Win64') != -1: + # target = 64bit + if os_bits == '32bit': + vcvars_platform = 'x86_amd64' # 32bit OS building 64bit app + else: + vcvars_platform = 'amd64' # 64bit OS building 64bit app + config_platform = 'x64' + else: # target = 32bit + vcvars_platform = 'x86' # 32/64bit OS building 32bit app + config_platform = config32 + + if mode == 'release': + config = 'Release' + else: + config = 'Debug' + + if generator.startswith('Visual Studio 10') or generator.startswith('Visual Studio 14'): + cmd = ('@echo off\n' + 'call "%s" %s \n' + 'cd "%s"\n' + 'msbuild /nologo %s /p:Configuration="%s" /p:Platform="%s" "%s"' + ) % (self.get_vcvarsall(generator), vcvars_platform, dir, args, config, config_platform, solution) + else: + config = config + '|' + config_platform + cmd = ('@echo off\n' + 'call "%s" %s \n' + 'cd "%s"\n' + 'vcbuild /nologo %s "%s" "%s"' + ) % (self.get_vcvarsall(generator), vcvars_platform, dir, args, solution, config) + + # Generate a batch file, since we can't use environment variables directly. + temp_bat = self.getBuildDir() + r'\vcbuild.bat' + file = open(temp_bat, 'w') + file.write(cmd) + file.close() - err = os.system(temp_bat) - if err != 0: - raise Exception('Microsoft compiler failed with error code: ' + str(err)) + err = os.system(temp_bat) + if err != 0: + raise Exception('Microsoft compiler failed with error code: ' + str(err)) - def ensure_setup_latest(self): - if not self.min_setup_version(self.setup_version): - self.setup() + def ensure_setup_latest(self): + if not self.min_setup_version(self.setup_version): + self.setup() - def reformat(self): - err = os.system( - r'tool\astyle\AStyle.exe ' - '--quiet --suffix=none --style=java --indent=force-tab=4 --recursive ' - 'lib/*.cpp lib/*.h cmd/*.cpp cmd/*.h') - - if err != 0: - raise Exception('Reformat failed with error code: ' + str(err)) + def reformat(self): + err = os.system( + r'tool\astyle\AStyle.exe ' + '--quiet --suffix=none --style=java --indent=force-tab=4 --recursive ' + 'lib/*.cpp lib/*.h cmd/*.cpp cmd/*.h') + + if err != 0: + raise Exception('Reformat failed with error code: ' + str(err)) - def printGeneratorList(self): - generators = self.get_generators() - keys = generators.keys() - keys.sort() - for k in keys: - print str(k) + ': ' + generators[k].cmakeName + def printGeneratorList(self): + generators = self.get_generators() + keys = generators.keys() + keys.sort() + for k in keys: + print str(k) + ': ' + generators[k].cmakeName - def getMacVersion(self): - if not self.macSdk: - raise Exception("Mac OS X SDK not set.") - - result = re.search('(\d+)\.(\d+)', self.macSdk) - if not result: - print versions - raise Exception("Could not find Mac OS X version.") + def getMacVersion(self): + if not self.macSdk: + raise Exception("Mac OS X SDK not set.") + + result = re.search('(\d+)\.(\d+)', self.macSdk) + if not result: + print versions + raise Exception("Could not find Mac OS X version.") - major = int(result.group(1)) - minor = int(result.group(2)) - return (major, minor) + major = int(result.group(1)) + minor = int(result.group(2)) + return (major, minor) - def getMacPackageName(self): + def getMacPackageName(self): - (major, minor) = self.getMacVersion() + (major, minor) = self.getMacVersion() - if major == 10: - if minor <= 4: - # 10.4: intel and power pc - arch = "Universal" - elif minor <= 6: - # 10.5: 32-bit intel - arch = "i386" - else: - # 10.7: 64-bit intel (gui only) - arch = "x86_64" - else: - raise Exception("Mac OS major version unknown: " + - str(major)) + if major == 10: + if minor <= 4: + # 10.4: intel and power pc + arch = "Universal" + elif minor <= 6: + # 10.5: 32-bit intel + arch = "i386" + else: + # 10.7: 64-bit intel (gui only) + arch = "x86_64" + else: + raise Exception("Mac OS major version unknown: " + + str(major)) - # version is major and minor with no dots (e.g. 106) - version = str(major) + str(minor) + # version is major and minor with no dots (e.g. 106) + version = str(major) + str(minor) - if (self.macDeploy == self.macSdk): - return "MacOSX%s-%s" % (version, arch) - else: - return "MacOSX-%s" % arch + if (self.macDeploy == self.macSdk): + return "MacOSX%s-%s" % (version, arch) + else: + return "MacOSX-%s" % arch - def reset(self): - if os.path.exists('build'): - shutil.rmtree('build') - - if os.path.exists('bin'): - shutil.rmtree('bin') - - if os.path.exists('lib'): - shutil.rmtree('lib') - - if os.path.exists('src/gui/tmp'): - shutil.rmtree('src/gui/tmp') - - # qt 4.3 generates ui_ files. - for filename in glob.glob("src/gui/ui_*"): - os.remove(filename) + def reset(self): + if os.path.exists('build'): + shutil.rmtree('build') + + if os.path.exists('bin'): + shutil.rmtree('bin') + + if os.path.exists('lib'): + shutil.rmtree('lib') + + if os.path.exists('src/gui/tmp'): + shutil.rmtree('src/gui/tmp') + + # qt 4.3 generates ui_ files. + for filename in glob.glob("src/gui/ui_*"): + os.remove(filename) # the command handler should be called only from hm.py (i.e. directly # from the command prompt). the purpose of this class is so that we # don't need to do argument handling all over the place in the internal # commands class. class CommandHandler: - ic = InternalCommands() - build_targets = [] - vcRedistDir = '' - qtDir = '' - - def __init__(self, argv, opts, args, verbose): - - self.ic.verbose = verbose - - self.opts = opts - self.args = args - - for o, a in self.opts: - if o == '--no-prompts': - self.ic.no_prompts = True - elif o in ('-g', '--generator'): - self.ic.generator_id = a - elif o == '--skip-gui': - self.ic.enableMakeGui = False - elif o == '--skip-core': - self.ic.enableMakeCore = False - elif o == '--skip-tests': - self.ic.enableMakeTests = False - elif o in ('-d', '--debug'): - self.build_targets += ['debug',] - elif o in ('-r', '--release'): - self.build_targets += ['release',] - elif o == '--vcredist-dir': - self.vcRedistDir = a - elif o == '--qt-dir': - self.qtDir = a - elif o == '--mac-sdk': - self.ic.macSdk = a - elif o == '--mac-deploy': - self.ic.macDeploy = a - elif o == '--mac-identity': - self.ic.macIdentity = a - - def about(self): - self.ic.about() - - def setup(self): - self.ic.setup() - - def configure(self): - self.ic.configureAll(self.build_targets) - - def build(self): - self.ic.build(self.build_targets) - - def clean(self): - self.ic.clean(self.build_targets) - - def update(self): - self.ic.update() - - def install(self): - print 'Not yet implemented: install' - - def doxygen(self): - self.ic.doxygen() - - def dist(self): - - type = None - if len(self.args) > 0: - type = self.args[0] + ic = InternalCommands() + build_targets = [] + vcRedistDir = '' + qtDir = '' + + def __init__(self, argv, opts, args, verbose): + + self.ic.verbose = verbose + + self.opts = opts + self.args = args + + for o, a in self.opts: + if o == '--no-prompts': + self.ic.no_prompts = True + elif o in ('-g', '--generator'): + self.ic.generator_id = a + elif o == '--skip-gui': + self.ic.enableMakeGui = False + elif o == '--skip-core': + self.ic.enableMakeCore = False + elif o == '--skip-tests': + self.ic.enableMakeTests = False + elif o in ('-d', '--debug'): + self.build_targets += ['debug',] + elif o in ('-r', '--release'): + self.build_targets += ['release',] + elif o == '--vcredist-dir': + self.vcRedistDir = a + elif o == '--qt-dir': + self.qtDir = a + elif o == '--mac-sdk': + self.ic.macSdk = a + elif o == '--mac-deploy': + self.ic.macDeploy = a + elif o == '--mac-identity': + self.ic.macIdentity = a + + def about(self): + self.ic.about() + + def setup(self): + self.ic.setup() + + def configure(self): + self.ic.configureAll(self.build_targets) + + def build(self): + self.ic.build(self.build_targets) + + def clean(self): + self.ic.clean(self.build_targets) + + def update(self): + self.ic.update() + + def install(self): + print 'Not yet implemented: install' + + def doxygen(self): + self.ic.doxygen() + + def dist(self): + + type = None + if len(self.args) > 0: + type = self.args[0] - self.ic.dist(type, self.vcRedistDir, self.qtDir) + self.ic.dist(type, self.vcRedistDir, self.qtDir) - def distftp(self): - type = None - host = None - user = None - password = None - dir = None - - if len(self.args) > 0: - type = self.args[0] - - for o, a in self.opts: - if o == '--host': - host = a - elif o == '--user': - user = a - elif o == '--pass': - password = a - elif o == '--dir': - dir = a - - if not host: - raise Exception('FTP host was not specified.') + def distftp(self): + type = None + host = None + user = None + password = None + dir = None + + if len(self.args) > 0: + type = self.args[0] + + for o, a in self.opts: + if o == '--host': + host = a + elif o == '--user': + user = a + elif o == '--pass': + password = a + elif o == '--dir': + dir = a + + if not host: + raise Exception('FTP host was not specified.') - ftp = ftputil.FtpUploader( - host, user, password, dir) - - self.ic.distftp(type, ftp) - - def destroy(self): - self.ic.destroy() - - def kill(self): - self.ic.kill() - - def usage(self): - self.ic.usage() - - def revision(self): - self.ic.revision() - - def reformat(self): - self.ic.reformat() - - def open(self): - self.ic.open() + ftp = ftputil.FtpUploader( + host, user, password, dir) + + self.ic.distftp(type, ftp) + + def destroy(self): + self.ic.destroy() + + def kill(self): + self.ic.kill() + + def usage(self): + self.ic.usage() + + def revision(self): + self.ic.revision() + + def reformat(self): + self.ic.reformat() + + def open(self): + self.ic.open() - def genlist(self): - self.ic.printGeneratorList() + def genlist(self): + self.ic.printGeneratorList() - def reset(self): - self.ic.reset() - - def signwin(self): - pfx = None - pwd = None - dist = False - for o, a in self.opts: - if o == '--pfx': - pfx = a - elif o == '--pwd': - pwd = a - elif o == '--dist': - dist = True - self.ic.signwin(pfx, pwd, dist) + def reset(self): + self.ic.reset() + + def signwin(self): + pfx = None + pwd = None + dist = False + for o, a in self.opts: + if o == '--pfx': + pfx = a + elif o == '--pwd': + pwd = a + elif o == '--dist': + dist = True + self.ic.signwin(pfx, pwd, dist) - def signmac(self): - self.ic.signmac() + def signmac(self): + self.ic.signmac()