]> git.lyx.org Git - lyx.git/blobdiff - development/scons/scons_utils.py
Scons: fix a config.h generation bug
[lyx.git] / development / scons / scons_utils.py
index 136ac7a2005c58515c817ff6fd5b482ef0492fb2..203a39a513a5a27a84bf51cbe4744215d4f193c7 100644 (file)
@@ -16,6 +16,24 @@ import os, sys, re, shutil, glob
 from SCons.Util import WhereIs
 
 
+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):
     " utility function: write or append lines to filename "
     # create directory if needed
@@ -58,19 +76,6 @@ def env_subst(target, source, env):
     #st = os.stat(str(source[0]))
     #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
-    else:
-        return ['%s/%s' % (build_dir, x) for x in files]
-
 #
 # autoconf tests
 #
@@ -153,24 +158,77 @@ int main()
     return ('int', 'int *', 'struct timeval *')
 
 
-def checkBoostLibraries(conf, lib, pathes):
-    ''' look for boost libraries '''
-    conf.Message('Checking for boost library %s... ' % lib)
-    for path in pathes:
+def checkBoostLibraries(conf, libs, lib_paths, inc_paths, version, isDebug):
+    ''' look for boost libraries
+      libs: library names
+      lib_paths: try these paths for boost libraries
+      inc_paths: try these paths for boost headers
+      version:   required boost version
+      isDebug:   if true, use debug libraries
+    '''
+    conf.Message('Checking for boost library %s... ' % ', '.join(libs))
+    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
-        if os.path.isfile(os.path.join(path, 'lib%s.a' % lib)):
-            conf.Result('yes')
-            return (path, lib)
-        # check things like libboost_iostreams-gcc.a
-        files = glob.glob(os.path.join(path, 'lib%s-*.a' % lib))
-        # if there are more than one, choose the first one
-        # FIXME: choose the best one.
-        if len(files) >= 1:
-            # get xxx-gcc from /usr/local/lib/libboost_xxx-gcc.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')
-            return (path, files[0].split(os.sep)[-1][3:-2])
-    conf.Result('n')
-    return ('','')
+            found_lib = True
+            lib_path = path
+            lib_names = libs
+            break
+        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))
+            # check things like libboost_iostreams-gcc-mt-d-1_33_1.a
+            if len(files) > 0:
+                # runtime code includes s,g,y,d,p,n, where we should look for
+                # d,g,y for debug, s,p,n for release
+                if isDebug:
+                    lib_files = filter(lambda x: re.search('libboost_%s-\w+-mt-[^spn]+-%s.a' % (lib, version), x), files)
+                else:
+                    lib_files = filter(lambda x: re.search('libboost_%s-\w+-mt-([^dgy]+-)*%s.a' % (lib, version), x), files)
+                if len(lib_files) == 0:
+                    print 'Warning: Can not find an appropriate boost library in %s.' % path
+                    lib_files = filter(lambda x: re.search('libboost_%s-[\w-]+%s.a' % (lib, version), x), files)
+                    if len(lib_files) > 0:
+                        print 'Use library %s' % lib_files[0]
+                if len(lib_files) > 0:
+                    # get xxx-gcc-1_33_1 from /usr/local/lib/libboost_xxx-gcc-1_33_1.a
+                    lib_names.append(lib_files[0].split(os.sep)[-1][3:-2])
+        if len(lib_names) == len(libs):
+            found_lib = True
+            lib_path = path
+            break
+    if not found_lib:
+        conf.Result('no')
+        return (None, None, None)
+    # check version number in boost/version.hpp
+    def isValidBoostDir(dir):
+        file = os.path.join(dir, 'boost', 'version.hpp')
+        version_string = '#define BOOST_LIB_VERSION "%s"' % version
+        return os.path.isfile(file) and version_string in open(file).read()
+    # check for boost header file
+    for path in inc_paths:
+        if isValidBoostDir(path):
+            inc_path = path
+            found_inc = True
+        else:   # check path/boost_1_xx_x/boost
+            dirs = glob.glob(os.path.join(path, 'boost-*'))
+            if len(dirs) > 0 and isValidBoostDir(dirs[0]):
+                inc_path = dirs[0]
+                found_inc = True
+    # return result
+    if found_inc:
+        conf.Result('yes')
+        return (lib_names, lib_path, inc_path)
+    else:
+        conf.Result('no')
+        return (None, None, None)
 
 
 def checkCommand(conf, cmd):
@@ -201,23 +259,12 @@ int main()
 def checkIconvConst(conf):
     ''' check the declaration of iconv '''
     check_iconv_const = '''
-#include <stdlib.h>
 #include <iconv.h>
-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
-
-int main()
-{
-    return 1;
+// 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('Check if the declaration of iconv needs const... ')
@@ -226,6 +273,26 @@ int main()
     return ret
 
 
+def checkSizeOfWChar(conf):
+    ''' check the size of wchar '''
+    check_sizeof_wchar = '''
+int i[ ( sizeof(wchar_t)==%d ? 1 : -1 ) ];
+int main()
+{
+    return 0;
+}
+'''
+    conf.Message('Check 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
+
+
 def createConfigFile(conf, config_file,
     config_pre = '', config_post = '',
     headers = [], functions = [], types = [], libs = [],
@@ -272,28 +339,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:
@@ -303,30 +370,30 @@ 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)
                 break
-        # if not found        
+        # if not found
         if not result[lib[1]]:
             cont += configString('/* #undef %s */' % lib[1], desc = description)
     # 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:
@@ -552,6 +619,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('''#!/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>/<dir>\/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