X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=development%2Fscons%2Fscons_utils.py;h=bb924cafc86d2c5248871278c0a04b4c020301f6;hb=8cc88bf1ecbbe2f09d310403726f1145d49236cf;hp=5030f07221497460c5beb3eb120a4a8d02f696a7;hpb=e85cfec9579464ac7eb36291ef308b47c6bddaaa;p=lyx.git diff --git a/development/scons/scons_utils.py b/development/scons/scons_utils.py index 5030f07221..bb924cafc8 100644 --- a/development/scons/scons_utils.py +++ b/development/scons/scons_utils.py @@ -13,7 +13,25 @@ # import os, sys, re, shutil, glob -from SCons.Util import WhereIs +from SCons.Util import * + + +def getVerFromConfigure(path): + " get lyx version from the AC_INIT line of configure.ac " + try: + config = open(os.path.join(path, 'configure.ac')) + except: + print "Can not open configure.ac. " + return 'x.x.x' + # find a line like follows + # AC_INIT(LyX,1.4.4svn,[lyx-devel@lists.lyx.org],[lyx]) + pat = re.compile('AC_INIT\([^,]+,([^,]+),') + for line in config.readlines(): + if pat.match(line): + (version,) = pat.match(line).groups() + return version.strip() + return 'x.x.x' + def writeToFile(filename, lines, append = False): @@ -50,7 +68,6 @@ def env_subst(target, source, env): # multi-line replacement val = val.replace('\n',r'\\n\\\n') contents = re.sub('@'+k+'@', val, contents) - contents = re.sub('%'+k+'%', val, contents) except: pass target_file.write(contents + "\n") @@ -59,17 +76,69 @@ def env_subst(target, source, env): #os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) -# -# glob filenames -# -def globSource(dir, pattern, build_dir = None, exclude = [], include = []): - ''' glob files, in dir and use build_dir as returned path name ''' - # exclude 'exclude+include' to avoid duplicate items in files - files = include + filter(lambda x: x not in exclude + include, glob.glob1(dir, pattern)) - if build_dir is None: - return files +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'] + " /V1 " + 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(env['NSISDEFINES'][d]) + ret += ' ' + # bundled? + if '-bundle.exe' in str(target[0]): + ret += '/DSETUPTYPE_BUNDLE=1 ' + for s in source: + ret += quoteIfSpaced(str(s)) + return ret + + +def env_toc(target, source, env): + '''Generate target from source files''' + # this is very tricky because we need to use installed lyx2lyx with + # correct lyx2lyx_version.py + sys.path.append(env['LYX2LYX_DEST']) + sys.path.append(env.Dir('$TOP_SRCDIR/lib/doc').abspath) + import doc_toc + # build toc + doc_toc.build_toc(str(target[0]), [file.abspath for file in source]) + + +def env_cat(target, source, env): + '''Cat source > target. Avoid pipe to increase portability''' + output = open(env.File(target[0]).abspath, 'w') + for src in source: + input = open(env.File(src).abspath) + output.write(input.read()) + input.close() + output.close() + + +def createResFromIcon(env, icon_file, rc_file): + ''' create a rc file with icon, and return res file (windows only) ''' + if os.name == 'nt': + rc_name = env.File(rc_file).abspath + dir = os.path.split(rc_name)[0] + if not os.path.isdir(dir): + os.makedirs(dir) + rc = open(rc_name, 'w') + print >> rc, 'IDI_ICON1 ICON DISCARDABLE "%s"' % \ + os.path.join(env.Dir('$TOP_SRCDIR').abspath, 'development', 'win32', + 'packaging', 'icons', icon_file).replace('\\', '\\\\') + rc.close() + return env.RES(rc_name) else: - return ['%s/%s' % (build_dir, x) for x in files] + return [] + # # autoconf tests @@ -111,7 +180,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; @@ -120,7 +189,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 @@ -153,65 +222,86 @@ int main() return ('int', 'int *', 'struct timeval *') -def checkBoostLibraries(conf, libs, lib_paths, inc_paths, isDebug): +def checkBoostLibraries(conf, libs, lib_paths, inc_paths, versions, isDebug): ''' look for boost libraries libs: library names lib_paths: try these paths for boost libraries inc_paths: try these paths for boost headers + versions: supported boost versions isDebug: if true, use debug libraries ''' conf.Message('Checking for boost library %s... ' % ', '.join(libs)) + libprefix = conf.env['LIBPREFIX'] + libsuffix = '(%s|%s)' % (conf.env['LIBSUFFIX'], conf.env['SHLIBSUFFIX']) found_lib = False found_inc = False lib_names = [] lib_path = None inc_path = None for path in lib_paths: - # direct form: e.g. libboost_iostreams.a - # ignore isDebug - if False not in [os.path.isfile(os.path.join(path, 'libboost_%s.a' % lib)) for lib in libs]: - conf.Result('yes') - found_lib = True - lib_path = path - lib_names = libs - break + conf.Log("Looking into %s\n" % path) for lib in libs: # get all the libs, then filter for the right library - files = glob.glob(os.path.join(path, 'libboost_%s-*.a' % lib)) + files = glob.glob(os.path.join(path, '%sboost_%s-*.*' % (libprefix, lib))) # check things like libboost_iostreams-gcc-mt-d-1_33_1.a if len(files) > 0: + conf.Log("Find boost libraries: %s\n" % files) + # runtime code includes s,g,y,d,p,n, where we should look for + # d,g,y for debug, s,p,n for release + lib_files = [] if isDebug: - files = filter(lambda x: re.search('libboost_%s-\w+-mt-d-[\d-]+' % lib, x), files) + for ver in versions: + lib_files += filter(lambda x: re.search('%sboost_%s-\w+-mt-[^spn]+-%s%s' % (libprefix, lib, ver, libsuffix), x), files) else: - files = filter(lambda x: re.search('libboost_%s-\w+-mt-[\d-]+' % lib, x), files) - if len(files) == 0: - print 'Warning: %s directory seems to have the boost libraries, but ' % path - print 'I can not find one that has the form lib%s-xxx-mt[-d]-x_xx_x.a' % lib - print 'Check your boost installation, or change select criteria in scons_util.py' - if len(files) > 0: - # get xxx-gcc-1_33_1 from /usr/local/lib/libboost_xxx-gcc-1_33_1.a - lib_names.append(files[0].split(os.sep)[-1][3:-2]) + for ver in versions: + lib_files += filter(lambda x: re.search('%sboost_%s-\w+-mt-([^dgy]+-)*%s%s' % (libprefix, lib, ver, libsuffix), x), files) + if len(lib_files) == 0: + # use alternative libraries + for ver in versions: + lib_files += filter(lambda x: re.search('%sboost_%s-[\w-]+%s%s' % (libprefix, lib, ver, libsuffix), x), files) + if len(lib_files) > 0: + # get xxx-gcc-1_33_1 from /usr/local/lib/libboost_xxx-gcc-1_33_1.a + name = lib_files[0].split(os.sep)[-1][len(libprefix):] + lib_names.append(name.split('.')[0]) + conf.Log("Qualified libraries: %s\n" % lib_names) + else: + conf.Log("No qualified library is found.\n") + break if len(lib_names) == len(libs): found_lib = True lib_path = path break if not found_lib: + if len(lib_names) == 0: + conf.Log("No boost library is found\n") + else: + conf.Log("Found boost libraries: %s\n" % lib_names) conf.Result('no') return (None, None, None) + # check version number in boost/version.hpp + def isValidBoostDir(dir): + version_file = os.path.join(dir, 'boost', 'version.hpp') + if not os.path.isfile(version_file): + return False + version_file_content = open(version_file).read() + version_strings = ['#define BOOST_LIB_VERSION "%s"' % ver for ver in versions] + return True in [x in version_file_content for x in version_strings] # check for boost header file for path in inc_paths: - # check path/boost/regex.h - if os.path.isfile(os.path.join(path, 'boost', 'regex.h')): + conf.Log("Checking for inc path: %s\n" % path) + if isValidBoostDir(path): inc_path = path found_inc = True - else: # check path/boost_1_xx_x/boost + else: # check path/boost_1_xx_x/boost dirs = glob.glob(os.path.join(path, 'boost-*')) - if len(dirs) > 0 and os.path.isfile(os.path.join(dirs[0], 'boost', 'regex.h')): + if len(dirs) > 0 and isValidBoostDir(dirs[0]): + conf.Log("Checing for sub directory: %s\n" % dirs[0]) inc_path = dirs[0] found_inc = True # return result if found_inc: conf.Result('yes') + conf.Log('Using boost libraries %s\n' % (', '.join(lib_names))) return (lib_names, lib_path, inc_path) else: conf.Result('no') @@ -228,6 +318,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 = ''' @@ -237,7 +351,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 @@ -246,28 +360,37 @@ int main() def checkIconvConst(conf): ''' check the declaration of iconv ''' check_iconv_const = ''' -#include #include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(__cplusplus) -#ifndef LIBICONV_DLL_EXPORTED -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#endif -#else -size_t iconv(); -#endif +// this declaration will fail when there already exists a non const char** +// version which returns size_t +double iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); +int main() { + return 0; +} +''' + conf.Message('Checking if the declaration of iconv needs const... ') + ret = conf.TryLink(check_iconv_const, '.c') + conf.Result(ret) + return ret + +def checkSizeOfWChar(conf): + ''' check the size of wchar ''' + check_sizeof_wchar = ''' +int i[ ( sizeof(wchar_t)==%d ? 1 : -1 ) ]; int main() { - return 1; + return 0; } ''' - conf.Message('Check if the declaration of iconv needs const... ') - ret = conf.TryLink(check_iconv_const, '.c') - conf.Result(ret) + 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'): + ret = 4 + else: + ret = 0 + conf.Result(str(ret)) return ret @@ -317,28 +440,28 @@ def createConfigFile(conf, config_file, description = "Define to 1 if you have the <%s> header file." % header[0] if (header[2] == 'c' and conf.CheckCHeader(header[0])) or \ (header[2] == 'cxx' and conf.CheckCXXHeader(header[0])): - result[header[1]] = True + result[header[1]] = 1 cont += configString('#define %s 1' % header[1], desc = description) else: - result[header[1]] = False + result[header[1]] = 0 cont += configString('/* #undef %s */' % header[1], desc = description) # functions for func in functions: description = "Define to 1 if you have the `%s' function." % func[0] if conf.CheckFunc(func[0], header=func[2]): - result[func[1]] = True + result[func[1]] = 1 cont += configString('#define %s 1' % func[1], desc = description) else: - result[func[1]] = False + result[func[1]] = 0 cont += configString('/* #undef %s */' % func[1], desc = description) # types for t in types: description = "Define to 1 if you have the `%s' type." % t[0] if conf.CheckType(t[0], includes=t[2]): - result[t[1]] = True + result[t[1]] = 1 cont += configString('#define %s 1' % t[1], desc = description) else: - result[t[1]] = False + result[t[1]] = 0 cont += configString('/* #undef %s */' % t[1], desc = description) # libraries for lib in libs: @@ -348,13 +471,13 @@ def createConfigFile(conf, config_file, else: lib_list = lib[0] # check if any of the lib exists - result[lib[1]] = False + result[lib[1]] = 0 # if user want the name of the lib detected if len(lib) == 3: result[lib[2]] = None for ll in lib_list: if conf.CheckLib(ll): - result[lib[1]] = True + result[lib[1]] = 1 if len(lib) == 3: result[lib[2]] = ll cont += configString('#define %s 1' % lib[1], desc = description) @@ -365,13 +488,13 @@ def createConfigFile(conf, config_file, # custom tests for test in custom_tests: if test[0]: - result[test[1]] = True + result[test[1]] = 1 if len(test) == 3: cont += configString('#define %s 1' % test[1], desc = test[2]) else: cont += configString(test[3], desc = test[2]) else: - result[test[1]] = False + result[test[1]] = 0 if len(test) == 3: cont += configString('/* #undef %s */' % test[1], desc = test[2]) else: @@ -597,6 +720,27 @@ SECTIONS return(ld_script) +def installCygwinPostinstallScript(path): + ''' Install lyx.sh ''' + postinstall_script = os.path.join(path, 'lyx.sh') + script = open(postinstall_script, 'w') + script.write(r'''#!/bin/sh + +# Add /usr/share/lyx/fonts to /etc/fonts/local.conf +# if it is not already there. +if [ -f /etc/fonts/local.conf ]; then + grep -q /usr/share/lyx/fonts /etc/fonts/local.conf + if [ $? -ne 0 ]; then + sed 's/^<\/fontconfig>/\/usr\/share\/lyx\/fonts<\/dir>\n<\/fontconfig>/' /etc/fonts/local.conf > /etc/fonts/local.conf.tmp + mv -f /etc/fonts/local.conf.tmp /etc/fonts/local.conf + fc-cache /usr/share/lyx/fonts + fi +fi + ''') + script.close() + return(postinstall_script) + + try: # these will be used under win32 import win32file