From db4499f4b1b276a9bafc2d5669a0ffc871f8b4c0 Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Thu, 25 Jan 2007 06:19:49 +0000 Subject: [PATCH] Scons: initial windows nsis installer support git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16846 a592a061-630c-0410-9148-cb99ea01b6c8 --- development/scons/SConstruct | 47 ++++++++++++++++++++-- development/scons/scons_manifest.py | 55 ++++++++++++++++++++++++++ development/scons/scons_utils.py | 61 ++++++++++++++++++++++++++--- 3 files changed, 154 insertions(+), 9 deletions(-) diff --git a/development/scons/SConstruct b/development/scons/SConstruct index 1aa414edfb..d792130809 100644 --- a/development/scons/SConstruct +++ b/development/scons/SConstruct @@ -590,6 +590,7 @@ conf = Configure(env, 'CheckSelectArgType' : utils.checkSelectArgType, 'CheckBoostLibraries' : utils.checkBoostLibraries, 'CheckCommand' : utils.checkCommand, + 'CheckNSIS' : utils.checkNSIS, 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd, 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES, 'CheckIconvConst' : utils.checkIconvConst, @@ -708,6 +709,10 @@ else: # check for msgfmt command env['MSGFMT'] = conf.CheckCommand('msgfmt') +# if under windows, check the nsis compiler +if platform_name == 'win32': + env['NSIS'] = conf.CheckNSIS() + # cygwin packaging requires the binaries to be stripped if platform_name == 'cygwin': env['STRIP'] = conf.CheckCommand('strip') @@ -1479,8 +1484,9 @@ def appExists(apppath, appname): return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath) targets = BUILD_TARGETS +build_installer = 'installer' in targets # msvc need to pass full target name, so I have to look for path/lyx etc -build_lyx = targets == [] or True in ['lyx' in x for x in targets] \ +build_lyx = build_installer or targets == [] or True in ['lyx' in x for x in targets] \ or 'install' in targets or 'all' in targets build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets @@ -1491,9 +1497,9 @@ build_frontends = build_lyx or 'frontends' in targets build_graphics = build_lyx or 'graphics' in targets build_controllers = build_lyx or 'controllers' in targets build_client = True in ['client' in x for x in targets] \ - or 'install' in targets or 'all' in targets + or 'install' in targets or 'all' in targets or build_installer build_tex2lyx = True in ['tex2lyx' in x for x in targets] \ - or 'install' in targets or 'all' in targets + or 'install' in targets or 'all' in targets or build_installer build_lyxbase = build_lyx or 'lyxbase' in targets build_po = 'po' in targets or 'install' in targets or 'all' in targets build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets @@ -1989,6 +1995,41 @@ if build_po: gmo_files.extend(env.Transfiles(f)) +if build_installer: + # + # build windows installer using NSIS + # + # NOTE: + # There is a nsis builder on scons wiki but it does not work with + # our lyx.nsi because it does not dig through all the include directives + # and find the dependencies automatically. Also, it can not parse + # OutFile in lyx.nsi since it is defined as SETUP_EXE which is in turn + # something rely on date. + # Because of this, I am doing a simple nsis builder here. + if platform_name != 'win32': + print 'installer target is only available for windows platform' + Exit(1) + if env.has_key('NSIS') and env['NSIS'] is not None: + # create a builder to strip and install + env['BUILDERS']['installer'] = Builder(generator=utils.env_nsis) + else: + print 'No nsis compiler is found. Existing...' + Exit(2) + installer = env.installer(# 'target.exe', + '$TOP_SRCDIR/development/Win32/packaging/installer/lyx.nsi') + # since I can not use a scanner, explicit dependent is required + env.Depends(installer, \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/%s' % x for x in win32_packaging_installer_files] + \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/components/%s' % x for x in win32_packaging_installer_components_files] + \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/dialogs/%s' % x for x in win32_packaging_installer_dialogs_files] + \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/graphics/%s' % x for x in win32_packaging_installer_graphics_files] + \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/include/%s' % x for x in win32_packaging_installer_include_files] + \ + ['$TOP_SRCDIR/development/Win32/packaging/installer/lang/%s' % x for x in win32_packaging_installer_lang_files ] + ) + print "installer is", installer + frontend_env.Alias('installer', installer) + + if 'install' in targets: # # this part is a bit messy right now. Since scons will provide diff --git a/development/scons/scons_manifest.py b/development/scons/scons_manifest.py index ca5317b55a..ecd71954d0 100644 --- a/development/scons/scons_manifest.py +++ b/development/scons/scons_manifest.py @@ -2382,3 +2382,58 @@ win32_bakoma_fonts = Split(''' msam10.ttf wasy10.ttf ''') + + +win32_packaging_installer_files = Split(''' + license.rtf + lyx.nsi + settings.nsh + settings.user.nsh +''') + + +win32_packaging_installer_components_files = Split(''' + configure.nsh + dicts.nsh + langselect.nsh + uninstall.nsh + viewer.nsh + core.nsh + external.nsh + reinstall.nsh + user.nsh +''') + + +win32_packaging_installer_dialogs_files = Split(''' + external.ini + langselect.ini + reinstall.ini + user.ini + viewer.ini +''') + + +win32_packaging_installer_graphics_files = Split(''' + header.bmp + wizard.bmp +''') + + +win32_packaging_installer_include_files = Split(''' + declarations.nsh + detection.nsh + filelists.nsh + gui.nsh + init.nsh + lang.nsh + windows.nsh +''') + + +win32_packaging_installer_lang_files = Split(''' + english.nsh + french.nsh + german.nsh + italian.nsh +''') diff --git a/development/scons/scons_utils.py b/development/scons/scons_utils.py index e377be94be..d9e2d07f32 100644 --- a/development/scons/scons_utils.py +++ b/development/scons/scons_utils.py @@ -13,7 +13,7 @@ # import os, sys, re, shutil, glob -from SCons.Util import WhereIs +from SCons.Util import * def getVerFromConfigure(path): @@ -76,6 +76,31 @@ def env_subst(target, source, env): #os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) +def env_nsis(source, target, env, for_signature): + ''' Get nsis command line ''' + def quoteIfSpaced(str): + if ' ' in str: + return '"' + str + '"' + else: + return str + ret = env['NSIS'] + " " + if env.has_key('NSISFLAGS'): + for flag in env['NSISFLAGS']: + ret += flag + ret += ' ' + if env.has_key('NSISDEFINES'): + for d in env['NSISDEFINES']: + ret += '/D'+d + if env['NSISDEFINES'][d]: + ret += '=' + quoteIfSpaced(toString(env['NSISDEFINES'][d],env)) + ret += ' ' + for s in source: + ret += quoteIfSpaced(str(s)) + print ret + Exit(0) + return ret + + def createResFromIcon(env, icon_file, rc_file): ''' create a rc file with icon, and return res file (windows only) ''' if os.name == 'nt': @@ -133,7 +158,7 @@ int main() def checkCXXGlobalCstd(conf): - ''' Check the use of std::tolower or tolower ''' + ''' Checking the use of std::tolower or tolower ''' check_global_cstd_source = ''' #include using std::tolower; @@ -142,7 +167,7 @@ int main() return 0; } ''' - conf.Message('Check for the use of global cstd... ') + conf.Message('Checking for the use of global cstd... ') ret = conf.TryLink(check_global_cstd_source, '.c') conf.Result(ret) return ret @@ -271,6 +296,30 @@ def checkCommand(conf, cmd): return res +def checkNSIS(conf): + ''' check the existence of nsis compiler, return the fullpath ''' + conf.Message('Checking for nsis compiler...') + res = None + if can_read_reg: + # If we can read the registry, get the NSIS command from it + try: + k = RegOpenKeyEx(hkey_mod.HKEY_LOCAL_MACHINE, + 'SOFTWARE\\NSIS') + val, tok = RegQueryValueEx(k,None) + ret = val + os.path.sep + 'makensis.exe' + if os.path.isfile(ret): + res = '"' + ret + '"' + else: + res = None + except: + pass # Couldn't find the key, just act like we can't read the registry + # Hope it's on the path + if res is None: + res = WhereIs('makensis.exe') + conf.Result(res is not None) + return res + + def checkLC_MESSAGES(conf): ''' check the definition of LC_MESSAGES ''' check_LC_MESSAGES = ''' @@ -280,7 +329,7 @@ int main() return LC_MESSAGES; } ''' - conf.Message('Check for LC_MESSAGES in locale.h... ') + conf.Message('Checking for LC_MESSAGES in locale.h... ') ret = conf.TryLink(check_LC_MESSAGES, '.c') conf.Result(ret) return ret @@ -297,7 +346,7 @@ int main() { return 0; } ''' - conf.Message('Check if the declaration of iconv needs const... ') + conf.Message('Checking if the declaration of iconv needs const... ') ret = conf.TryLink(check_iconv_const, '.c') conf.Result(ret) return ret @@ -312,7 +361,7 @@ int main() return 0; } ''' - conf.Message('Check the size of wchar_t... ') + conf.Message('Checking the size of wchar_t... ') if conf.TryLink(check_sizeof_wchar % 2, '.cpp'): ret = 2 elif conf.TryLink(check_sizeof_wchar % 4, '.cpp'): -- 2.39.5