From: Bo Peng Date: Mon, 8 May 2006 21:03:01 +0000 (+0000) Subject: Some fixes to the scons-based building sytem, from Bo Peng (ben.bob@gmail.com) X-Git-Tag: 1.6.10~13247 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=4b5fae61d3ab116fdf766fde5d2655416bf6e90f;p=features.git Some fixes to the scons-based building sytem, from Bo Peng (ben.bob@gmail.com) * SConstruct: add extra_inc_path1, fix mingw logged spawn, try to handle QtCore4 etc * src/SConscript: remove lyx_base library * src/frontends/qt4/SConscript: remove some extra files * Move scons_utils.py and qt4.py to config directory git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13813 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/SConstruct b/SConstruct index 956e0d2e06..debe41c47c 100644 --- a/SConstruct +++ b/SConstruct @@ -35,6 +35,7 @@ # # * use extra_inc_path, extra_lib_path, qt_dir, qt_inc_path # qt_lib_path to help locate qt and other libraries +# (there are extra_inc_path1, extra_lib_path1 for now) # # * (Important) use scons logfile=logfile.log to enable command line # logging. (default is no logging) @@ -63,7 +64,8 @@ import os, sys -# scons_util defines a few utility function +# config/scons_utils.py defines a few utility function +sys.path.append('config') import scons_utils as utils #---------------------------------------------------------- @@ -205,6 +207,8 @@ opts.AddOptions( # extra include and libpath PathOption('extra_inc_path', 'Extra include path', '.'), PathOption('extra_lib_path', 'Extra library path', '.'), + PathOption('extra_inc_path1', 'Extra include path', '.'), + PathOption('extra_lib_path1', 'Extra library path', '.'), # enable assertion, (config.h has ENABLE_ASSERTIOS BoolOption('assertions', 'Use assertions', True), # enable warning, (config.h has WITH_WARNINGS) @@ -315,6 +319,10 @@ if ARGUMENTS.has_key('extra_inc_path'): env.Append(CPPPATH = [ARGUMENTS['extra_inc_path']]) if ARGUMENTS.has_key('extra_lib_path'): env.Append(LIBPATH = [ARGUMENTS['extra_lib_path']]) +if ARGUMENTS.has_key('extra_inc_path1'): + env.Append(CPPPATH = [ARGUMENTS['extra_inc_path1']]) +if ARGUMENTS.has_key('extra_lib_path1'): + env.Append(LIBPATH = [ARGUMENTS['extra_lib_path1']]) # # this is a bit out of place (after auto-configration) @@ -362,13 +370,14 @@ elif env['frontend'] == 'qt4': succ = False # first: try pkg_config if env['HAS_PKG_CONFIG']: - succ = conf.CheckPackage('QtCore') + succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4') env['QT4_PKG_CONFIG'] = succ # second: try to link to it if not succ: # FIXME: under linux, I can test the following perfectly # However, under windows, lib names need to passed as libXXX4.a ... - succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') + succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \ + conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();') # third: try to look up the path if not succ: succ = True @@ -379,7 +388,9 @@ elif env['frontend'] == 'qt4': succ = False break # still can not find it - if not succ: + if succ: + print "Qt4 libraries are found." + else: print 'Did not find qt libraries, exiting!' Exit(1) @@ -660,7 +671,10 @@ try: elif frontend == 'qt4': # local qt4 toolset from # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html - env['QT_LIB'] = ['QtCore', 'QtGui', 'Qt3Support'] + if platform_name == "win32": + env['QT_LIB'] = ['QtCore4', 'QtGui4', 'Qt3Support4'] + else: + env['QT_LIB'] = ['QtCore', 'QtGui', 'Qt3Support'] env['EXTRA_LIBS'] = env['QT_LIB'] except: print "Can not locate qt tools" diff --git a/config/qt4.py b/config/qt4.py new file mode 100644 index 0000000000..593b018386 --- /dev/null +++ b/config/qt4.py @@ -0,0 +1,373 @@ +import re +import os.path + +import SCons.Defaults +import SCons.Tool +import SCons.Util + + +class ToolQtWarning(SCons.Warnings.Warning): + pass +class GeneratedMocFileNotIncluded(ToolQtWarning): + pass +class QtdirNotFound(ToolQtWarning): + pass +SCons.Warnings.enableWarningClass(ToolQtWarning) + +qrcinclude_re = re.compile(r'([^<]*)', re.M) + + +header_extensions = [".h", ".hxx", ".hpp", ".hh"] +if SCons.Util.case_sensitive_suffixes('.h', '.H'): + header_extensions.append('.H') +#cplusplus = __import__('c++', globals(), locals(), ['Scons.Tools']) +#cxx_suffixes = cplusplus.CXXSuffixes +cxx_suffixes = [".C", ".c", ".cxx", ".cpp", ".cc"] + +def _checkMocIncluded(target, source, env): + moc = target[0] + cpp = source[0] + # looks like cpp.includes is cleared before the build stage :-( + # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ + path = SCons.Defaults.CScan.path_function(env, moc.cwd) + includes = SCons.Defaults.CScan(cpp, env, path) + if not moc in includes: + SCons.Warnings.warn( + GeneratedMocFileNotIncluded, + "Generated moc file '%s' is not included by '%s'" % + (str(moc), str(cpp))) + +def _find_file(filename, paths, node_factory): + retval = None + for dir in paths: + node = node_factory(filename, dir) + if node.rexists(): + return node + return None + +class _Automoc: + """ + Callable class, which works as an emitter for Programs, SharedLibraries and + StaticLibraries. + """ + + def __init__(self, objBuilderName): + self.objBuilderName = objBuilderName + + def __call__(self, target, source, env): + """ + Smart autoscan function. Gets the list of objects for the Program + or Lib. Adds objects and builders for the special qt files. + """ + try: + if int(env.subst('$QT_AUTOSCAN')) == 0: + return target, source + except ValueError: + pass + try: + debug = int(env.subst('$QT_DEBUG')) + except ValueError: + debug = 0 + + # some shortcuts used in the scanner + FS = SCons.Node.FS.default_fs + splitext = SCons.Util.splitext + objBuilder = getattr(env, self.objBuilderName) + + # some regular expressions: + # Q_OBJECT detection + q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') + # cxx and c comment 'eater' + #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') + # CW: something must be wrong with the regexp. See also bug #998222 + # CURRENTLY THERE IS NO TEST CASE FOR THAT + + # The following is kind of hacky to get builders working properly (FIXME) + objBuilderEnv = objBuilder.env + objBuilder.env = env + mocBuilderEnv = env.Moc4.env + env.Moc4.env = env + + # make a deep copy for the result; MocH objects will be appended + out_sources = source[:] + + for obj in source: + if not obj.has_builder(): + # binary obj file provided + if debug: + print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) + continue + cpp = obj.sources[0] + if not splitext(str(cpp))[1] in cxx_suffixes: + if debug: + print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) + # c or fortran source + continue + #cpp_contents = comment.sub('', cpp.get_contents()) + cpp_contents = cpp.get_contents() + h=None + for h_ext in header_extensions: + # try to find the header file in the corresponding source + # directory + hname = splitext(cpp.name)[0] + h_ext + h = _find_file(hname, + (cpp.get_dir(),), + FS.File) + if h: + if debug: + print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) + #h_contents = comment.sub('', h.get_contents()) + h_contents = h.get_contents() + break + if not h and debug: + print "scons: qt: no header for '%s'." % (str(cpp)) + if h and q_object_search.search(h_contents): + # h file with the Q_OBJECT macro found -> add moc_cpp + moc_cpp = env.Moc4(h) + moc_o = objBuilder(moc_cpp) + out_sources.append(moc_o) + #moc_cpp.target_scanner = SCons.Defaults.CScan + if debug: + print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) + if cpp and q_object_search.search(cpp_contents): + # cpp file with Q_OBJECT macro found -> add moc + # (to be included in cpp) + moc = env.Moc4(cpp) + env.Ignore(moc, moc) + if debug: + print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) + #moc.source_scanner = SCons.Defaults.CScan + # restore the original env attributes (FIXME) + objBuilder.env = objBuilderEnv + env.Moc4.env = mocBuilderEnv + + return (target, out_sources) + +AutomocShared = _Automoc('SharedObject') +AutomocStatic = _Automoc('StaticObject') + +def _detect(env): + """Not really safe, but fast method to detect the QT library""" + + QTDIR = env.get('QTDIR',None) + if QTDIR!=None : return QTDIR + + QTDIR = os.environ.get('QTDIR',None) + if QTDIR!=None : return QTDIR + + moc = env.WhereIs('moc-qt4') or env.WhereIs('moc') + if moc: + SCons.Warnings.warn( + QtdirNotFound, + "QTDIR variable is not defined, using moc executable as a hint (QTDIR=%s)" % QTDIR) + return os.path.dirname(os.path.dirname(moc)) + + SCons.Warnings.warn( + QtdirNotFound, + "Could not detect qt, using empty QTDIR") + return None + +def generate(env): + """Add Builders and construction variables for qt to an Environment.""" + + print "Loading qt4 tool..." + + def locateQt4Command(env, command, qtdir) : + fullpath1 = os.path.join(qtdir,'bin',command +'-qt4') + if os.access(fullpath1, os.X_OK) or \ + os.access(fullpath1+".exe", os.X_OK): + return fullpath1 + fullpath2 = os.path.join(qtdir,'bin',command) + if os.access(fullpath2, os.X_OK) or \ + os.access(fullpath2+".exe", os.X_OK): + return fullpath2 + fullpath = env.Detect([command+'-qt4', command]) + if not (fullpath is None) : return fullpath + raise "Qt4 command '" + command + "' not found. Tried: " + fullpath1 + " and "+ fullpath2 + + + CLVar = SCons.Util.CLVar + Action = SCons.Action.Action + Builder = SCons.Builder.Builder + splitext = SCons.Util.splitext + + # the basics + env['QTDIR'] = _detect(env) + env['QT4_MOC'] = locateQt4Command(env,'moc', env['QTDIR']) + env['QT4_UIC'] = locateQt4Command(env,'uic', env['QTDIR']) + env['QT4_RCC'] = locateQt4Command(env,'rcc', env['QTDIR']) + env['QT4_LUPDATE'] = locateQt4Command(env,'lupdate', env['QTDIR']) + env['QT4_LRELEASE'] = locateQt4Command(env,'lrelease', env['QTDIR']) + + # Should the qt tool try to figure out, which sources are to be moc'ed ? + env['QT4_AUTOSCAN'] = 1 + + # Some QT specific flags. I don't expect someone wants to + # manipulate those ... + env['QT4_UICDECLFLAGS'] = CLVar('') + env['QT4_MOCFROMHFLAGS'] = CLVar('') + env['QT4_MOCFROMCXXFLAGS'] = CLVar('-i') + env['QT4_QRCFLAGS'] = '' + + # suffixes/prefixes for the headers / sources to generate + env['QT4_MOCHPREFIX'] = 'moc_' + env['QT4_MOCHSUFFIX'] = '$CXXFILESUFFIX' + env['QT4_MOCCXXPREFIX'] = 'moc_' + env['QT4_MOCCXXSUFFIX'] = '.moc' + env['QT4_UISUFFIX'] = '.ui' + env['QT4_UICDECLPREFIX'] = 'ui_' + env['QT4_UICDECLSUFFIX'] = '.h' + env['QT4_QRCSUFFIX'] = '.qrc', + env['QT4_QRCCXXSUFFIX'] = '$CXXFILESUFFIX' + env['QT4_QRCCXXPREFIX'] = 'qrc_' + + env['QT4_LIB'] = '' # KLUDGE to avoid linking qt3 library + + # Translation builder + tsbuilder = Builder( + action ='$QT4_LUPDATE $SOURCES -ts $TARGETS', + multi=1 + ) + env.Append( BUILDERS = { 'Ts': tsbuilder } ) + qmbuilder = Builder( + action =[ + '$QT4_LRELEASE $SOURCE', + ], + src_suffix = '.ts', + suffix = '.qm', + single_source = True + ) + env.Append( BUILDERS = { 'Qm': qmbuilder } ) + + # Resource builder + def scanResources(node, env, path, arg): + contents = node.get_contents() + includes = qrcinclude_re.findall(contents) + return includes + qrcscanner = env.Scanner(name = 'qrcfile', + function = scanResources, + argument = None, + skeys = ['.qrc']) + qrcbuilder = Builder( + action ='$QT4_RCC $QT4_QRCFLAGS $SOURCE -o $TARGET', + source_scanner = qrcscanner, + src_suffix = '$QT4_QRCSUFFIX', + suffix = '$QT4_QRCCXXSUFFIX', + prefix = '$QT4_QRCCXXPREFIX', + single_source = True + ) + env.Append( BUILDERS = { 'Qrc': qrcbuilder } ) + + # Interface builder + #env['QT4_UIC4COM'] = [ + # CLVar('$QT4_UIC $QT4_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), + # ] + env['QT4_UIC4COM'] = '$QT4_UIC -o $TARGET $SOURCE' + uic4builder = Builder( + action='$QT4_UIC4COM', + src_suffix='$QT4_UISUFFIX', + suffix='$QT4_UICDECLSUFFIX', + #prefix='$QT4_UICDECLPREFIX', + single_source = True + ) + env.Append( BUILDERS = { 'Uic4': uic4builder } ) + + # Metaobject builder + env['QT4_MOCFROMHCOM'] = ( + '$QT4_MOC $QT4_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE') + env['QT4_MOCFROMCXXCOM'] = [ + CLVar('$QT4_MOC $QT4_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), + Action(_checkMocIncluded,None)] + mocBld = Builder(action={}, prefix={}, suffix={}) + for h in header_extensions: + mocBld.add_action(h, '$QT4_MOCFROMHCOM') + mocBld.prefix[h] = '$QT4_MOCHPREFIX' + mocBld.suffix[h] = '$QT4_MOCHSUFFIX' + for cxx in cxx_suffixes: + mocBld.add_action(cxx, '$QT4_MOCFROMCXXCOM') + mocBld.prefix[cxx] = '$QT4_MOCCXXPREFIX' + mocBld.suffix[cxx] = '$QT4_MOCCXXSUFFIX' + env.Append( BUILDERS = { 'Moc4': mocBld } ) + + # er... no idea what that was for + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + static_obj.src_builder.append('Uic4') + shared_obj.src_builder.append('Uic4') + + # We use the emitters of Program / StaticLibrary / SharedLibrary + # to scan for moc'able files + # We can't refer to the builders directly, we have to fetch them + # as Environment attributes because that sets them up to be called + # correctly later by our emitter. + env.AppendUnique(PROGEMITTER =[AutomocStatic], + SHLIBEMITTER=[AutomocShared], + LIBEMITTER =[AutomocStatic], + # Of course, we need to link against the qt libraries + CPPPATH=[os.path.join('$QTDIR', 'include')], + LIBPATH=[os.path.join('$QTDIR', 'lib')], + LIBS=['$QT4_LIB']) + + import new + method = new.instancemethod(enable_modules, env, SCons.Environment) + env.EnableQt4Modules=method + +def enable_modules(self, modules, debug=False) : + import sys + + validModules = [ + 'QtCore', + 'QtGui', + 'QtOpenGL', + 'Qt3Support', + # The next modules have not been tested yet so, please + # maybe they require additional work on non Linux platforms + 'QtSql', + 'QtNetwork', + 'QtSvg', + 'QtTest', + 'QtXml', + 'QtUiTools', + ] + pclessModules = [ + 'QtUiTools', + 'QtUiTools_debug', + ] + invalidModules=[] + for module in modules: + if module not in validModules : + invalidModules.append(module) + if invalidModules : + raise "Modules %s are not Qt4 modules. Valid Qt4 modules are: %s"% \ + (str(invalidModules),str(validModules)) + + # TODO: Check whether we should add QT_CORE_LIB, QT_XML_LIB, QT_NETWORK_LIB... + if 'QtGui' in modules: + self.AppendUnique(CPPFLAGS='-DQT_GUI_LIB') + + if sys.platform == "linux2" : + if debug : modules = [module+"_debug" for module in modules] + for module in modules : + if module in pclessModules : + # self.AppendUnique(LIBS=[module]) + self.AppendUnique(LIBPATH=[os.path.join(self["QTDIR"],"lib",module)]) + self.AppendUnique(CPPPATH=[os.path.join(self["QTDIR"],"include","qt4",module)]) + modules.remove(module) + self.ParseConfig('PKG_CONFIG_PATH=%s/lib pkg-config %s --libs --cflags'% + ( + self['QTDIR'], + ' '.join(modules))) + return + if sys.platform == "win32" : + if debug : debugSuffix = 'd' + else : debugSuffix = '' + self.AppendUnique(LIBS=[lib+'4'+debugSuffix for lib in modules]) + if 'QtOpenGL' in modules: + self.AppendUnique(LIBS=['opengl32']) + self.AppendUnique(CPPPATH=[ '$QTDIR/include/'+module + for module in modules]) + self.AppendUnique(LIBPATH=['$QTDIR/lib']) + + +def exists(env): + return _detect(env) + diff --git a/config/scons_utils.py b/config/scons_utils.py new file mode 100644 index 0000000000..0d47c41584 --- /dev/null +++ b/config/scons_utils.py @@ -0,0 +1,778 @@ +# vi:filetype=python:expandtab:tabstop=2:shiftwidth=2 +# +# file scons_utils.py +# +# This file is part of LyX, the document processor. +# Licence details can be found in the file COPYING. +# +# \author Bo Peng +# Full author contact details are available in file CREDITS. +# +# This file defines all the utility functions for the +# scons-based build system of lyx +# + +import os, sys, re, shutil, glob + +def writeToFile(filename, lines, append = False): + " utility function: write or append lines to filename " + if append: + file = open(filename, 'a') + else: + file = open(filename, 'w') + file.write(lines) + file.close() + + +def addToConfig(lines): + ''' utility function: shortcut for appending lines to outfile + add newline at the end of lines. + ''' + if lines.strip() != '': + writeToFile(os.path.join('src', 'config.h'), + lines + '\n\n', append = True) + + +def printEnvironment(env, keys=[]): + ''' used to check profile settings ''' + dict = env.Dictionary() + if len(keys) == 0: + keys = dict.keys() + keys.sort() + for key in keys: + try: + # try to expand, but this is not always possible + print key, '=', env.subst('$'+key) + except: + print '<>:', key, '=', dict[key] + + +def env_subst(target, source, env): + ''' subst variables in source by those in env, and output to target + source and target are scons File() objects + + %key% (not key itself) is an indication of substitution + ''' + assert len(target) == 1 + assert len(source) == 1 + target_file = file(str(target[0]), "w") + source_file = file(str(source[0]), "r") + + contents = source_file.read() + for (k, v) in env.items(): + try: + contents = re.sub('%'+k+'%', v, contents) + except: + pass + target_file.write(contents + "\n") + target_file.close() + #st = os.stat(str(source[0])) + #os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) + + +def env_filecopy(target, source, env): + shutil.copy(str(source[0]), str(target[0])) + + +# +# autoconf tests +# + +def checkPkgConfig(conf, version): + ''' Return false if pkg_config does not exist, or is too old ''' + conf.Message('Checking for pkg-config...') + ret = conf.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] + conf.Result(ret) + return ret + + +def checkPackage(conf, pkg): + ''' check if pkg is under the control of conf ''' + conf.Message('Checking for package %s...' % pkg) + ret = conf.TryAction("pkg-config --print-errors --exists %s" % pkg)[0] + conf.Result(ret) + return ret + + +def startConfigH(config_h): + ''' Write the first part of config.h ''' + writeToFile(config_h, +'''/* src/config.h. Generated by scon. */ + +/* -*- C++ -*- */ +/* + * \file config.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * This is the compilation configuration file for LyX. + * It was generated by scon. + * You might want to change some of the defaults if something goes wrong + * during the compilation. + */ + +#ifndef _CONFIG_H +#define _CONFIG_H +''') + + +def endConfigH(config_h): + ''' Write the last part of config.h ''' + writeToFile(config_h, ''' +/************************************************************ + ** You should not need to change anything beyond this point */ + +#ifndef HAVE_STRERROR +#if defined(__cplusplus) +extern "C" +#endif +char * strerror(int n); +#endif + +#ifdef HAVE_MKSTEMP +#ifndef HAVE_DECL_MKSTEMP +#if defined(__cplusplus) +extern "C" +#endif +int mkstemp(char*); +#endif +#endif + +#ifdef __EMX__ +# include "support/os2_defines.h" +#endif + +#if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM) +# define USE_BOOST_FORMAT 1 +#else +# define USE_BOOST_FORMAT 0 +#endif + +#define BOOST_USER_CONFIG + +#if !defined(ENABLE_ASSERTIONS) +# define BOOST_DISABLE_ASSERTS 1 +#endif +#define BOOST_ENABLE_ASSERT_HANDLER 1 + +#define BOOST_DISABLE_THREADS 1 +#define BOOST_NO_WREGEX 1 +#define BOOST_NO_WSTRING 1 + +#ifdef __CYGWIN__ +# define BOOST_POSIX 1 +#endif + +#if defined(HAVE_NEWAPIS_H) +# define WANT_GETFILEATTRIBUTESEX_WRAPPER 1 +#endif + +#endif +''', append=True) + + +#HAVE_PUTENV +def checkPutenv(conf): + check_putenv_source = """ +#include +int main() +{ + putenv(""); + return(0); +} +""" + conf.Message('Checking for putenv... ') + ret = conf.TryLink(check_putenv_source, '.c') + conf.Result(ret) + return ret + + +#HAVE_DECL_ISTREAMBUF_ITERATOR +def checkIstreambufIterator(conf): + check_istreambuf_iterator_source = """ +#include +#include +int main() +{ + std::istreambuf_iterator iter; + return 0; +} +""" + conf.Message('Checking for iostreambuf::iterator... ') + ret = conf.TryLink(check_istreambuf_iterator_source, '.cpp') + conf.Result(ret) + return ret + + +#MKDIR_TAKES_ONE_ARG +def checkMkdirOneArg(conf): + check_mkdir_one_arg_source = """ +#include +int main() +{ + mkdir("somedir"); +} +""" + conf.Message('Checking for the number of args for mkdir... ') + ret = conf.TryLink(check_mkdir_one_arg_source, '.c') + if ret: + conf.Result('one') + else: + conf.Result('two') + return ret + + +#HAVE_STD_COUNT +def checkStdCount(conf): + check_std_count_source = """ +#include +using std::count; +int countChar(char * b, char * e, char const c) +{ + return count(b, e, c); +} + +int main() +{ + char a[] = "hello"; + int i = countChar(a, a + 5, 'l'); +} +""" + conf.Message('Checking for std::count... ') + ret = conf.TryLink(check_std_count_source, '.cpp') + conf.Result(ret) + return ret + + +# SELECT_TYPE_ARG1 +# SELECT_TYPE_ARG234 +# SELECT_TYPE_ARG5 +def checkSelectArgType(conf): + ''' Adapted from autoconf ''' + conf.Message('Checking for arg types for select... ') + for arg234 in ['fd_set *', 'int *', 'void *']: + for arg1 in ['int', 'size_t', 'unsigned long', 'unsigned']: + for arg5 in ['struct timeval *', 'const struct timeval *']: + check_select_source = ''' +#if HAVE_SYS_SELECT_H +# include +#endif +#if HAVE_SYS_SOCKET_H +# include +#endif +extern int select (%s, %s, %s, %s, %s); +int main() +{ + return(0); +} +''' % (arg1, arg234, arg234, arg234, arg5) + ret = conf.TryLink(check_select_source, '.c') + if ret: + conf.Result(ret) + return (arg1, arg234, arg5) + conf.Result('no (use default)') + 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: + # 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 + conf.Result('yes') + return (path, files[0].split(os.sep)[-1][3:-2]) + conf.Result('n') + return ('','') + + +import SCons.Node +def processLang(env, folder): + """ Process translations (.po files) in a po/ dir + This is copied from KDE knetstats-1.5/admin/kde.py + + FIXME: imcomplete + """ + import glob + dir=SCons.Node.FS.default_fs.Dir(folder).srcnode() + fld=dir.srcnode() + tmptransfiles = glob.glob(str(fld)+'/*.po') + + transfiles=[] + if env.has_key('_BUILDDIR_'): + bdir=env['_BUILDDIR_'] + for dir in env.make_list(tmptransfiles): + transfiles.append( env.join(bdir, dir) ) + else: + transfiles=tmptransfiles + + env['MSGFMT'] = 'msgfmt' + env['BUILDERS']['Transfiles']=SCons.Builder.Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po') + languages=None + # FIXME: KDE has this ARGS thing... + #if env['ARGS'] and env['ARGS'].has_key('languages'): + # languages=env.make_list(env['ARGS']['languages']) + mydir=SCons.Node.FS.default_fs.Dir('.') + for f in transfiles: + fname=f.replace(mydir.abspath, '') + file=SCons.Node.FS.default_fs.File(fname) + country = SCons.Util.splitext(file.name)[0] + if not languages or country in languages: + result = env.Transfiles(file) + # FIXME + # dir=env.join( getInstDirForResType(env, 'KDELOCALE'), country) + # env.bksys_install(env.join(dir, 'LC_MESSAGES'), result, destfile=appname+'.mo') + + +def installCygwinLDScript(path): + ''' Install i386pe.x-no-rdata ''' + ld_script = os.path.join(path, 'i386pe.x-no-rdata') + script = open(ld_script, 'w') + script.write('''/* specific linker script avoiding .rdata sections, for normal executables +for a reference see +http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html +http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html +*/ +OUTPUT_FORMAT(pei-i386) +SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api"); +ENTRY(_mainCRTStartup) +SECTIONS +{ + .text __image_base__ + __section_alignment__ : + { + *(.init) + *(.text) + *(SORT(.text$*)) + *(.glue_7t) + *(.glue_7) + ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); + ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); + *(.fini) + /* ??? Why is .gcc_exc here? */ + *(.gcc_exc) + PROVIDE (etext = .); + *(.gcc_except_table) + } + /* The Cygwin32 library uses a section to avoid copying certain data + on fork. This used to be named ".data". The linker used + to include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. Instead, we name the section + ".data_cygwin_nocopy" and explictly include it after __data_end__. */ + .data BLOCK(__section_alignment__) : + { + __data_start__ = . ; + *(.data) + *(.data2) + *(SORT(.data$*)) + *(.rdata) + *(SORT(.rdata$*)) + *(.eh_frame) + ___RUNTIME_PSEUDO_RELOC_LIST__ = .; + __RUNTIME_PSEUDO_RELOC_LIST__ = .; + *(.rdata_runtime_pseudo_reloc) + ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + __data_end__ = . ; + *(.data_cygwin_nocopy) + } + .rdata BLOCK(__section_alignment__) : + { + } + .pdata BLOCK(__section_alignment__) : + { + *(.pdata) + } + .bss BLOCK(__section_alignment__) : + { + __bss_start__ = . ; + *(.bss) + *(COMMON) + __bss_end__ = . ; + } + .edata BLOCK(__section_alignment__) : + { + *(.edata) + } + /DISCARD/ : + { + *(.debug$S) + *(.debug$T) + *(.debug$F) + *(.drectve) + } + .idata BLOCK(__section_alignment__) : + { + /* This cannot currently be handled with grouped sections. + See pe.em:sort_sections. */ + SORT(*)(.idata$2) + SORT(*)(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7) + } + .CRT BLOCK(__section_alignment__) : + { + ___crt_xc_start__ = . ; + *(SORT(.CRT$XC*)) /* C initialization */ + ___crt_xc_end__ = . ; + ___crt_xi_start__ = . ; + *(SORT(.CRT$XI*)) /* C++ initialization */ + ___crt_xi_end__ = . ; + ___crt_xl_start__ = . ; + *(SORT(.CRT$XL*)) /* TLS callbacks */ + /* ___crt_xl_end__ is defined in the TLS Directory support code */ + ___crt_xp_start__ = . ; + *(SORT(.CRT$XP*)) /* Pre-termination */ + ___crt_xp_end__ = . ; + ___crt_xt_start__ = . ; + *(SORT(.CRT$XT*)) /* Termination */ + ___crt_xt_end__ = . ; + } + .tls BLOCK(__section_alignment__) : + { + ___tls_start__ = . ; + *(.tls) + *(.tls$) + *(SORT(.tls$*)) + ___tls_end__ = . ; + } + .endjunk BLOCK(__section_alignment__) : + { + /* end is deprecated, don't use it */ + PROVIDE (end = .); + PROVIDE ( _end = .); + __end__ = .; + } + .rsrc BLOCK(__section_alignment__) : + { + *(.rsrc) + *(SORT(.rsrc$*)) + } + .reloc BLOCK(__section_alignment__) : + { + *(.reloc) + } + .stab BLOCK(__section_alignment__) (NOLOAD) : + { + *(.stab) + } + .stabstr BLOCK(__section_alignment__) (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section. Unlike other targets that fake this by putting the + section VMA at 0, the PE format will not allow it. */ + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_aranges) + } + .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_pubnames) + } + /* DWARF 2. */ + .debug_info BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_info) *(.gnu.linkonce.wi.*) + } + .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_abbrev) + } + .debug_line BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_line) + } + .debug_frame BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_frame) + } + .debug_str BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_str) + } + .debug_loc BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_loc) + } + .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_macinfo) + } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_weaknames) + } + .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_funcnames) + } + .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_typenames) + } + .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_varnames) + } + /* DWARF 3. */ + .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_ranges) + } +} +''') + script.close() + return(ld_script) + + +try: + # these will be used under win32 + import win32file + import win32event + import win32process + import win32security +except: + # does not matter if it fails on other systems + pass + + +class loggedSpawn: + def __init__(self, env, logfile, longarg, info): + # save the spawn system + self.env = env + self.logfile = logfile + # clear the logfile (it may not exist) + if logfile != '': + # this will overwrite existing content. + writeToFile(logfile, info, append=False) + # + self.longarg = longarg + # get hold of the old spawn? (necessary?) + self._spawn = env['SPAWN'] + + # define new SPAWN + def spawn(self, sh, escape, cmd, args, spawnenv): + # get command line + newargs = ' '.join(map(escape, args[1:])) + cmdline = cmd + " " + newargs + # + # if log is not empty, write to it + if self.logfile != '': + # this tend to be slow (?) but ensure correct output + # Note that cmdline may be long so I do not escape it + try: + # since this is not an essential operation, proceed if things go wrong here. + writeToFile(self.logfile, cmd + " " + ' '.join(args[1:]) + '\n', append=True) + except: + print "Warning: can not write to log file ", self.logfile + # + # if the command is not too long, use the old + if not self.longarg or len(cmdline) < 8000: + exit_code = self._spawn(sh, escape, cmd, args, spawnenv) + else: + sAttrs = win32security.SECURITY_ATTRIBUTES() + StartupInfo = win32process.STARTUPINFO() + for var in spawnenv: + spawnenv[var] = spawnenv[var].encode('ascii', 'replace') + # check for any special operating system commands + if cmd == 'del': + for arg in args[1:]: + win32file.DeleteFile(arg) + exit_code = 0 + else: + # otherwise execute the command. + hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo) + win32event.WaitForSingleObject(hProcess, win32event.INFINITE) + exit_code = win32process.GetExitCodeProcess(hProcess) + win32file.CloseHandle(hProcess); + win32file.CloseHandle(hThread); + return exit_code + + +def setLoggedSpawn(env, logfile = '', longarg=False, info=''): + ''' This function modify env and allow logging of + commands to a logfile. If the argument is too long + a win32 spawn will be used instead of the system one + ''' + # + # create a new spwn object + ls = loggedSpawn(env, logfile, longarg, info) + # replace the old SPAWN by the new function + env['SPAWN'] = ls.spawn + + +## def CheckPython(context, minver): +## context.Message('Checking for Python >= %s...' % '.'.join(str(x) for x in minver)) +## try: +## python = context.env['PYTHON'] +## except KeyError: +## try: +## python = os.environ['PYTHON'] +## except KeyError: +## python = WhereIs("python") +## if not python: +## python = python = WhereIs("python%i.%i" % (minver[0], minver[1])) +## minverhex = 0 +## minver = list(minver) + [0, 0, 0, 0] +## for i in xrange(0, 4): +## minverhex = (minverhex << 8) + minver[i] +## prog = "import sys; sys.exit(sys.hexversion >= %s)" % minverhex +## if python is None: +## python = 'python' +## try: +## result = Popen([python, "-c", prog]).wait() +## except OSError: +## context.Result(False) +## return False +## context.Result(result) +## if result: +## context.env.Replace(PYTHON=python) +## proc = Popen([python, "-c", "import sys; print sys.version[:3]"], stdout=PIPE) +## pyver = proc.communicate()[0].rstrip() +## context.env.Replace(PYTHON_VERSION=pyver) +## context.env.Replace(pythondir="$prefix/lib/python$PYTHON_VERSION/site-packages") +## context.env.Replace(pyexecdir="${exec_prefix}/lib/python$PYTHON_VERSION/site-packages") +## return result +## +## def DistSources(env, node): +## env.DistFiles(_get_sources(env, node)) +## +## def DistFiles(env, files): +## assert isinstance(files, (list, tuple)) +## DISTFILES = [env.File(fname) for fname in files] +## env.AppendUnique(DISTFILES=DISTFILES) +## +## +## def make_distdir(target=None, source=None, env=None): +## distdir = env.subst('$DISTDIR') +## Execute(Delete(distdir)) +## Execute(Mkdir(distdir)) +## for fnode in env["DISTFILES"]: +## dirname, fname = os.path.split(str(fnode)) +## if dirname: +## distdirname = os.path.join(distdir, dirname) +## if not os.path.exists(distdirname): +## Execute(Mkdir(distdirname)) +## Execute(Copy(os.path.join(distdir, dirname, fname), str(fnode))) +## +## def make_dist(target=None, source=None, env=None): +## return Popen([env['TAR'], "-zcf", +## env.subst("${PACKAGE}-${VERSION}.tar.gz"), +## env.subst('$DISTDIR')]).wait() +## +## def make_distcheck(target=None, source=None, env=None): +## distdir = env.subst('$DISTDIR') +## distcheckinstdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-instdir-')) +## distcheckdestdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-destdir-')) +## instdirs = [os.path.join(distcheckinstdir, d) for d in +## 'lib', 'share', 'bin', 'include'] +## for dir_ in instdirs: +## Execute(Mkdir(dir_)) +## +## cmd = env.subst("cd $DISTDIR && scons DESTDIR=%s prefix=%s" +## " && scons check && scons install") %\ +## (os.path.join(distcheckdestdir, ''), distcheckinstdir) +## status = Popen(cmd, shell=True).wait() +## if status: +## return status +## ## Check that inst dirs are empty (to catch cases of $DESTDIR not being honored +## for dir_ in instdirs: +## if os.listdir(dir_): +## raise SCons.Errors.BuildError(target, "%s not empy" % dir_) +## ## Check that something inside $DESTDIR was installed +## dir_ = os.path.join(distcheckdestdir, distcheckinstdir) +## if not os.path.exists(dir_): +## raise SCons.Errors.BuildError(target, "%s does not exist" % dir_) +## Execute(Delete(distcheckinstdir)) +## Execute(Delete(distcheckdestdir)) +## Execute(Delete(distdir)) +## +## def InstallWithDestDir(self, dir_, source): +## dir_ = '${DESTDIR}' + str(dir_) +## return SConsEnvironment.Install(self, dir_, source) +## +## +## def InstallAsWithDestDir(self, target, source): +## target = '${DESTDIR}' + str(target) +## return SConsEnvironment.InstallAs(self, target, source) +## +## def generate(env): +## env.EnsureSConsVersion(0, 96, 91) +## +## opts = Options(['options.cache'], ARGUMENTS) +## opts.Add(PathOption('prefix', 'Installation prefix', '/usr/local')) +## opts.Add(PathOption('exec_prefix', 'Installation prefix blah blah', +## '$prefix')) +## opts.Add(PathOption('libdir', +## 'Installation prefix for architecture dependent files', '$prefix/lib')) +## opts.Add(PathOption('includedir', +## 'Installation prefix for C header files', '$prefix/include')) +## opts.Add(PathOption('datadir', +## 'Installation prefix for architecture independent files', '$prefix/share')) +## opts.Add(PathOption('bindir', 'Installation prefix for programs', '$prefix/bin')) +## opts.Add(PathOption('DESTDIR', 'blah blah', None)) +## opts.Update(env) +## opts.Save('options.cache', env) +## SConsEnvironment.Help(env, opts.GenerateHelpText(env)) +## +## env.Append(CPPFLAGS=r' -DVERSION=\"$VERSION\"') +## env.Append(CCFLAGS=ARGUMENTS.get('CCFLAGS', '-g -O2')) +## +## env['GNOME_TESTS'] = dict(CheckPython=CheckPython, +## CheckPythonHeaders=CheckPythonHeaders, +## PkgCheckModules=PkgCheckModules) +## +## SConsEnvironment.DistSources = DistSources +## SConsEnvironment.DistFiles = DistFiles +## env['DISTDIR'] = "${PACKAGE}-${VERSION}" +## +## #env.Command(env.Dir("$DISTDIR"), None, make_distdir) +## +## distdir_alias = env.Alias("distdir", None, make_distdir) +## dist_alias = env.Alias("dist", None, make_dist) +## env.Depends(dist_alias, distdir_alias) +## distcheck_alias = env.Alias("distcheck", None, make_distcheck) +## env.Depends(distcheck_alias, distdir_alias) +## env.AlwaysBuild(env.Alias('check')) +## +## #env['TARFLAGS'] ='-c -z' +## #env['TARSUFFIX'] = '.tar.gz' +## #tar = env.Tar('${PACKAGE}-${VERSION}.tar.gz', "${DISTDIR}") +## #env.Depends(tar, distdir_alias) +## #print env['DEFAULT_TARGETS'] +## +## #env.Depends(distdir_alias, "${DISTFILES}") +## #env.Alias('dist', tar) +## env.AlwaysBuild('dist') +## env.AlwaysBuild('distdir') +## env.AlwaysBuild('distcheck') +## env.DistFiles(['SConstruct', 'scons/gnome.py']) +## +## env['BUILDERS']['EnvSubstFile'] = SCons.Builder.Builder(action=env_subst) +## +## SConsEnvironment.PythonByteCompile = env.Action(byte_compile_python) +## +## env.Install = new.instancemethod(InstallWithDestDir, env, env.__class__) +## env.InstallAs = new.instancemethod(InstallAsWithDestDir, env, env.__class__) +## +## +## + diff --git a/qt4.py b/qt4.py deleted file mode 100644 index 40aef1271f..0000000000 --- a/qt4.py +++ /dev/null @@ -1,373 +0,0 @@ -import re -import os.path - -import SCons.Defaults -import SCons.Tool -import SCons.Util - - -class ToolQtWarning(SCons.Warnings.Warning): - pass -class GeneratedMocFileNotIncluded(ToolQtWarning): - pass -class QtdirNotFound(ToolQtWarning): - pass -SCons.Warnings.enableWarningClass(ToolQtWarning) - -qrcinclude_re = re.compile(r'([^<]*)', re.M) - - -header_extensions = [".h", ".hxx", ".hpp", ".hh"] -if SCons.Util.case_sensitive_suffixes('.h', '.H'): - header_extensions.append('.H') -#cplusplus = __import__('c++', globals(), locals(), ['Scons.Tools']) -#cxx_suffixes = cplusplus.CXXSuffixes -cxx_suffixes = [".c", ".cxx", ".cpp", ".cc", ".C"] - -def _checkMocIncluded(target, source, env): - moc = target[0] - cpp = source[0] - # looks like cpp.includes is cleared before the build stage :-( - # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ - path = SCons.Defaults.CScan.path_function(env, moc.cwd) - includes = SCons.Defaults.CScan(cpp, env, path) - if not moc in includes: - SCons.Warnings.warn( - GeneratedMocFileNotIncluded, - "Generated moc file '%s' is not included by '%s'" % - (str(moc), str(cpp))) - -def _find_file(filename, paths, node_factory): - retval = None - for dir in paths: - node = node_factory(filename, dir) - if node.rexists(): - return node - return None - -class _Automoc: - """ - Callable class, which works as an emitter for Programs, SharedLibraries and - StaticLibraries. - """ - - def __init__(self, objBuilderName): - self.objBuilderName = objBuilderName - - def __call__(self, target, source, env): - """ - Smart autoscan function. Gets the list of objects for the Program - or Lib. Adds objects and builders for the special qt files. - """ - try: - if int(env.subst('$QT_AUTOSCAN')) == 0: - return target, source - except ValueError: - pass - try: - debug = int(env.subst('$QT_DEBUG')) - except ValueError: - debug = 0 - - # some shortcuts used in the scanner - FS = SCons.Node.FS.default_fs - splitext = SCons.Util.splitext - objBuilder = getattr(env, self.objBuilderName) - - # some regular expressions: - # Q_OBJECT detection - q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') - # cxx and c comment 'eater' - #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') - # CW: something must be wrong with the regexp. See also bug #998222 - # CURRENTLY THERE IS NO TEST CASE FOR THAT - - # The following is kind of hacky to get builders working properly (FIXME) - objBuilderEnv = objBuilder.env - objBuilder.env = env - mocBuilderEnv = env.Moc4.env - env.Moc4.env = env - - # make a deep copy for the result; MocH objects will be appended - out_sources = source[:] - - for obj in source: - if not obj.has_builder(): - # binary obj file provided - if debug: - print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) - continue - cpp = obj.sources[0] - if not splitext(str(cpp))[1] in cxx_suffixes: - if debug: - print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) - # c or fortran source - continue - #cpp_contents = comment.sub('', cpp.get_contents()) - cpp_contents = cpp.get_contents() - h=None - for h_ext in header_extensions: - # try to find the header file in the corresponding source - # directory - hname = splitext(cpp.name)[0] + h_ext - h = _find_file(hname, - (cpp.get_dir(),), - FS.File) - if h: - if debug: - print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) - #h_contents = comment.sub('', h.get_contents()) - h_contents = h.get_contents() - break - if not h and debug: - print "scons: qt: no header for '%s'." % (str(cpp)) - if h and q_object_search.search(h_contents): - # h file with the Q_OBJECT macro found -> add moc_cpp - moc_cpp = env.Moc4(h) - moc_o = objBuilder(moc_cpp) - out_sources.append(moc_o) - #moc_cpp.target_scanner = SCons.Defaults.CScan - if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) - if cpp and q_object_search.search(cpp_contents): - # cpp file with Q_OBJECT macro found -> add moc - # (to be included in cpp) - moc = env.Moc4(cpp) - env.Ignore(moc, moc) - if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) - #moc.source_scanner = SCons.Defaults.CScan - # restore the original env attributes (FIXME) - objBuilder.env = objBuilderEnv - env.Moc4.env = mocBuilderEnv - - return (target, out_sources) - -AutomocShared = _Automoc('SharedObject') -AutomocStatic = _Automoc('StaticObject') - -def _detect(env): - """Not really safe, but fast method to detect the QT library""" - - QTDIR = env.get('QTDIR',None) - if QTDIR!=None : return QTDIR - - QTDIR = os.environ.get('QTDIR',None) - if QTDIR!=None : return QTDIR - - moc = env.WhereIs('moc-qt4') or env.WhereIs('moc') - if moc: - SCons.Warnings.warn( - QtdirNotFound, - "QTDIR variable is not defined, using moc executable as a hint (QTDIR=%s)" % QTDIR) - return os.path.dirname(os.path.dirname(moc)) - - SCons.Warnings.warn( - QtdirNotFound, - "Could not detect qt, using empty QTDIR") - return None - -def generate(env): - """Add Builders and construction variables for qt to an Environment.""" - - print "Loading qt4 tool..." - - def locateQt4Command(env, command, qtdir) : - fullpath = env.Detect([command+'-qt4', command]) - if not (fullpath is None) : return fullpath - fullpath1 = os.path.join(qtdir,'bin',command +'-qt4') - if os.access(fullpath1, os.X_OK) or \ - os.access(fullpath1+".exe", os.X_OK): - return fullpath1 - fullpath2 = os.path.join(qtdir,'bin',command) - if os.access(fullpath2, os.X_OK) or \ - os.access(fullpath2+".exe", os.X_OK): - return fullpath2 - raise "Qt4 command '" + command + "' not found. Tried: " + fullpath1 + " and "+ fullpath2 - - - CLVar = SCons.Util.CLVar - Action = SCons.Action.Action - Builder = SCons.Builder.Builder - splitext = SCons.Util.splitext - - # the basics - env['QTDIR'] = _detect(env) - env['QT4_MOC'] = locateQt4Command(env,'moc', env['QTDIR']) - env['QT4_UIC'] = locateQt4Command(env,'uic', env['QTDIR']) - env['QT4_RCC'] = locateQt4Command(env,'rcc', env['QTDIR']) - env['QT4_LUPDATE'] = locateQt4Command(env,'lupdate', env['QTDIR']) - env['QT4_LRELEASE'] = locateQt4Command(env,'lrelease', env['QTDIR']) - - # Should the qt tool try to figure out, which sources are to be moc'ed ? - env['QT4_AUTOSCAN'] = 1 - - # Some QT specific flags. I don't expect someone wants to - # manipulate those ... - env['QT4_UICDECLFLAGS'] = CLVar('') - env['QT4_MOCFROMHFLAGS'] = CLVar('') - env['QT4_MOCFROMCXXFLAGS'] = CLVar('-i') - env['QT4_QRCFLAGS'] = '' - - # suffixes/prefixes for the headers / sources to generate - env['QT4_MOCHPREFIX'] = 'moc_' - env['QT4_MOCHSUFFIX'] = '$CXXFILESUFFIX' - env['QT4_MOCCXXPREFIX'] = 'moc_' - env['QT4_MOCCXXSUFFIX'] = '.moc' - env['QT4_UISUFFIX'] = '.ui' - env['QT4_UICDECLPREFIX'] = 'ui_' - env['QT4_UICDECLSUFFIX'] = '.h' - env['QT4_QRCSUFFIX'] = '.qrc', - env['QT4_QRCCXXSUFFIX'] = '$CXXFILESUFFIX' - env['QT4_QRCCXXPREFIX'] = 'qrc_' - - env['QT4_LIB'] = '' # KLUDGE to avoid linking qt3 library - - # Translation builder - tsbuilder = Builder( - action ='$QT4_LUPDATE $SOURCES -ts $TARGETS', - multi=1 - ) - env.Append( BUILDERS = { 'Ts': tsbuilder } ) - qmbuilder = Builder( - action =[ - '$QT4_LRELEASE $SOURCE', - ], - src_suffix = '.ts', - suffix = '.qm', - single_source = True - ) - env.Append( BUILDERS = { 'Qm': qmbuilder } ) - - # Resource builder - def scanResources(node, env, path, arg): - contents = node.get_contents() - includes = qrcinclude_re.findall(contents) - return includes - qrcscanner = env.Scanner(name = 'qrcfile', - function = scanResources, - argument = None, - skeys = ['.qrc']) - qrcbuilder = Builder( - action ='$QT4_RCC $QT4_QRCFLAGS $SOURCE -o $TARGET', - source_scanner = qrcscanner, - src_suffix = '$QT4_QRCSUFFIX', - suffix = '$QT4_QRCCXXSUFFIX', - prefix = '$QT4_QRCCXXPREFIX', - single_source = True - ) - env.Append( BUILDERS = { 'Qrc': qrcbuilder } ) - - # Interface builder - env['QT4_UIC4COM'] = [ - CLVar('$QT4_UIC $QT4_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), - ] - uic4builder = Builder( - action='$QT4_UIC4COM', - src_suffix='$QT4_UISUFFIX', - suffix='$QT4_UICDECLSUFFIX', - prefix='$QT4_UICDECLPREFIX', - single_source = True - ) - env.Append( BUILDERS = { 'Uic4': uic4builder } ) - - # Metaobject builder - env['QT4_MOCFROMHCOM'] = ( - '$QT4_MOC $QT4_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE') - env['QT4_MOCFROMCXXCOM'] = [ - CLVar('$QT4_MOC $QT4_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), - Action(_checkMocIncluded,None)] - mocBld = Builder(action={}, prefix={}, suffix={}) - for h in header_extensions: - mocBld.add_action(h, '$QT4_MOCFROMHCOM') - mocBld.prefix[h] = '$QT4_MOCHPREFIX' - mocBld.suffix[h] = '$QT4_MOCHSUFFIX' - for cxx in cxx_suffixes: - mocBld.add_action(cxx, '$QT4_MOCFROMCXXCOM') - mocBld.prefix[cxx] = '$QT4_MOCCXXPREFIX' - mocBld.suffix[cxx] = '$QT4_MOCCXXSUFFIX' - env.Append( BUILDERS = { 'Moc4': mocBld } ) - - # er... no idea what that was for - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - static_obj.src_builder.append('Uic4') - shared_obj.src_builder.append('Uic4') - - # We use the emitters of Program / StaticLibrary / SharedLibrary - # to scan for moc'able files - # We can't refer to the builders directly, we have to fetch them - # as Environment attributes because that sets them up to be called - # correctly later by our emitter. - env.AppendUnique(PROGEMITTER =[AutomocStatic], - SHLIBEMITTER=[AutomocShared], - LIBEMITTER =[AutomocStatic], - # Of course, we need to link against the qt libraries - CPPPATH=[os.path.join('$QTDIR', 'include')], - LIBPATH=[os.path.join('$QTDIR', 'lib')], - LIBS=['$QT4_LIB']) - - import new - method = new.instancemethod(enable_modules, env, SCons.Environment) - env.EnableQt4Modules=method - -def enable_modules(self, modules, debug=False) : - import sys - - validModules = [ - 'QtCore', - 'QtGui', - 'QtOpenGL', - 'Qt3Support', - # The next modules have not been tested yet so, please - # maybe they require additional work on non Linux platforms - 'QtSql', - 'QtNetwork', - 'QtSvg', - 'QtTest', - 'QtXml', - 'QtUiTools', - ] - pclessModules = [ - 'QtUiTools', - 'QtUiTools_debug', - ] - invalidModules=[] - for module in modules: - if module not in validModules : - invalidModules.append(module) - if invalidModules : - raise "Modules %s are not Qt4 modules. Valid Qt4 modules are: %s"% \ - (str(invalidModules),str(validModules)) - - # TODO: Check whether we should add QT_CORE_LIB, QT_XML_LIB, QT_NETWORK_LIB... - if 'QtGui' in modules: - self.AppendUnique(CPPFLAGS='-DQT_GUI_LIB') - - if sys.platform == "linux2" : - if debug : modules = [module+"_debug" for module in modules] - for module in modules : - if module in pclessModules : - # self.AppendUnique(LIBS=[module]) - self.AppendUnique(LIBPATH=[os.path.join(self["QTDIR"],"lib",module)]) - self.AppendUnique(CPPPATH=[os.path.join(self["QTDIR"],"include","qt4",module)]) - modules.remove(module) - # modified by Bo Peng (/lib/pkgconfig => /lib) - self.ParseConfig('PKG_CONFIG_PATH=%s/lib pkg-config %s --libs --cflags'% - ( - self['QTDIR'], - ' '.join(modules))) - return - if sys.platform == "win32" : - if debug : debugSuffix = 'd' - else : debugSuffix = '' - self.AppendUnique(LIBS=[lib+'4'+debugSuffix for lib in modules]) - if 'QtOpenGL' in modules: - self.AppendUnique(LIBS=['opengl32']) - self.AppendUnique(CPPPATH=[ '$QTDIR/include/'+module - for module in modules]) - self.AppendUnique(LIBPATH=['$QTDIR/lib']) - - -def exists(env): - return _detect(env) - diff --git a/scons_utils.py b/scons_utils.py deleted file mode 100644 index 7da71d52ec..0000000000 --- a/scons_utils.py +++ /dev/null @@ -1,773 +0,0 @@ -# vi:filetype=python:expandtab:tabstop=2:shiftwidth=2 -# -# file scons_utils.py -# -# This file is part of LyX, the document processor. -# Licence details can be found in the file COPYING. -# -# \author Bo Peng -# Full author contact details are available in file CREDITS. -# -# This file defines all the utility functions for the -# scons-based build system of lyx -# - -import os, sys, re, shutil, glob - -def writeToFile(filename, lines, append = False): - " utility function: write or append lines to filename " - if append: - file = open(filename, 'a') - else: - file = open(filename, 'w') - file.write(lines) - file.close() - - -def addToConfig(lines): - ''' utility function: shortcut for appending lines to outfile - add newline at the end of lines. - ''' - if lines.strip() != '': - writeToFile(os.path.join('src', 'config.h'), - lines + '\n\n', append = True) - - -def printEnvironment(env, keys=[]): - ''' used to check profile settings ''' - dict = env.Dictionary() - if len(keys) == 0: - keys = dict.keys() - keys.sort() - for key in keys: - try: - # try to expand, but this is not always possible - print key, '=', env.subst('$'+key) - except: - print '<>:', key, '=', dict[key] - - -def env_subst(target, source, env): - ''' subst variables in source by those in env, and output to target - source and target are scons File() objects - - %key% (not key itself) is an indication of substitution - ''' - assert len(target) == 1 - assert len(source) == 1 - target_file = file(str(target[0]), "w") - source_file = file(str(source[0]), "r") - - contents = source_file.read() - for (k, v) in env.items(): - try: - contents = re.sub('%'+k+'%', v, contents) - except: - pass - target_file.write(contents + "\n") - target_file.close() - #st = os.stat(str(source[0])) - #os.chmod(str(target[0]), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) - - -def env_filecopy(target, source, env): - shutil.copy(str(source[0]), str(target[0])) - - -# -# autoconf tests -# - -def checkPkgConfig(conf, version): - ''' Return false if pkg_config does not exist, or is too old ''' - conf.Message('Checking for pkg-config...') - ret = conf.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] - conf.Result(ret) - return ret - - -def checkPackage(conf, pkg): - ''' check if pkg is under the control of conf ''' - conf.Message('Checking for package %s...' % pkg) - ret = conf.TryAction("pkg-config --print-errors --exists %s" % pkg)[0] - conf.Result(ret) - return ret - - -def startConfigH(config_h): - ''' Write the first part of config.h ''' - writeToFile(config_h, -'''/* src/config.h. Generated by scon. */ - -/* -*- C++ -*- */ -/* - * \file config.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * This is the compilation configuration file for LyX. - * It was generated by scon. - * You might want to change some of the defaults if something goes wrong - * during the compilation. - */ - -#ifndef _CONFIG_H -#define _CONFIG_H -''') - - -def endConfigH(config_h): - ''' Write the last part of config.h ''' - writeToFile(config_h, ''' -/************************************************************ - ** You should not need to change anything beyond this point */ - -#ifndef HAVE_STRERROR -#if defined(__cplusplus) -extern "C" -#endif -char * strerror(int n); -#endif - -#ifdef HAVE_MKSTEMP -#ifndef HAVE_DECL_MKSTEMP -#if defined(__cplusplus) -extern "C" -#endif -int mkstemp(char*); -#endif -#endif - -#ifdef __EMX__ -# include "support/os2_defines.h" -#endif - -#if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM) -# define USE_BOOST_FORMAT 1 -#else -# define USE_BOOST_FORMAT 0 -#endif - -#define BOOST_USER_CONFIG - -#if !defined(ENABLE_ASSERTIONS) -# define BOOST_DISABLE_ASSERTS 1 -#endif -#define BOOST_ENABLE_ASSERT_HANDLER 1 - -#define BOOST_DISABLE_THREADS 1 -#define BOOST_NO_WREGEX 1 -#define BOOST_NO_WSTRING 1 - -#ifdef __CYGWIN__ -# define BOOST_POSIX 1 -#endif - -#if defined(HAVE_NEWAPIS_H) -# define WANT_GETFILEATTRIBUTESEX_WRAPPER 1 -#endif - -#endif -''', append=True) - - -#HAVE_PUTENV -def checkPutenv(conf): - check_putenv_source = """ -#include -int main() -{ - putenv(""); - return(0); -} -""" - conf.Message('Checking for putenv... ') - ret = conf.TryLink(check_putenv_source, '.c') - conf.Result(ret) - return ret - - -#HAVE_DECL_ISTREAMBUF_ITERATOR -def checkIstreambufIterator(conf): - check_istreambuf_iterator_source = """ -#include -#include -int main() -{ - std::istreambuf_iterator iter; - return 0; -} -""" - conf.Message('Checking for iostreambuf::iterator... ') - ret = conf.TryLink(check_istreambuf_iterator_source, '.cpp') - conf.Result(ret) - return ret - - -#MKDIR_TAKES_ONE_ARG -def checkMkdirOneArg(conf): - check_mkdir_one_arg_source = """ -#include -int main() -{ - mkdir("somedir"); -} -""" - conf.Message('Checking for the number of args for mkdir... ') - ret = conf.TryLink(check_mkdir_one_arg_source, '.c') - if ret: - conf.Result('one') - else: - conf.Result('two') - return ret - - -#HAVE_STD_COUNT -def checkStdCount(conf): - check_std_count_source = """ -#include -using std::count; -int countChar(char * b, char * e, char const c) -{ - return count(b, e, c); -} - -int main() -{ - char a[] = "hello"; - int i = countChar(a, a + 5, 'l'); -} -""" - conf.Message('Checking for std::count... ') - ret = conf.TryLink(check_std_count_source, '.cpp') - conf.Result(ret) - return ret - - -# SELECT_TYPE_ARG1 -# SELECT_TYPE_ARG234 -# SELECT_TYPE_ARG5 -def checkSelectArgType(conf): - ''' Adapted from autoconf ''' - conf.Message('Checking for arg types for select... ') - for arg234 in ['fd_set *', 'int *', 'void *']: - for arg1 in ['int', 'size_t', 'unsigned long', 'unsigned']: - for arg5 in ['struct timeval *', 'const struct timeval *']: - check_select_source = ''' -#if HAVE_SYS_SELECT_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include -#endif -extern int select (%s, %s, %s, %s, %s); -int main() -{ - return(0); -} -''' % (arg1, arg234, arg234, arg234, arg5) - ret = conf.TryLink(check_select_source, '.c') - if ret: - conf.Result(ret) - return (arg1, arg234, arg5) - conf.Result('no (use default)') - 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: - # 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 - conf.Result('yes') - return (path, files[0].split(os.sep)[-1][3:-2]) - conf.Result('n') - return ('','') - - -import SCons.Node -def processLang(env, folder): - """ Process translations (.po files) in a po/ dir - This is copied from KDE knetstats-1.5/admin/kde.py - - FIXME: imcomplete - """ - import glob - dir=SCons.Node.FS.default_fs.Dir(folder).srcnode() - fld=dir.srcnode() - tmptransfiles = glob.glob(str(fld)+'/*.po') - - transfiles=[] - if env.has_key('_BUILDDIR_'): - bdir=env['_BUILDDIR_'] - for dir in env.make_list(tmptransfiles): - transfiles.append( env.join(bdir, dir) ) - else: - transfiles=tmptransfiles - - env['MSGFMT'] = 'msgfmt' - env['BUILDERS']['Transfiles']=SCons.Builder.Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po') - languages=None - # FIXME: KDE has this ARGS thing... - #if env['ARGS'] and env['ARGS'].has_key('languages'): - # languages=env.make_list(env['ARGS']['languages']) - mydir=SCons.Node.FS.default_fs.Dir('.') - for f in transfiles: - fname=f.replace(mydir.abspath, '') - file=SCons.Node.FS.default_fs.File(fname) - country = SCons.Util.splitext(file.name)[0] - if not languages or country in languages: - result = env.Transfiles(file) - # FIXME - # dir=env.join( getInstDirForResType(env, 'KDELOCALE'), country) - # env.bksys_install(env.join(dir, 'LC_MESSAGES'), result, destfile=appname+'.mo') - - -def installCygwinLDScript(path): - ''' Install i386pe.x-no-rdata ''' - ld_script = os.path.join(path, 'i386pe.x-no-rdata') - script = open(ld_script, 'w') - script.write('''/* specific linker script avoiding .rdata sections, for normal executables -for a reference see -http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html -http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html -*/ -OUTPUT_FORMAT(pei-i386) -SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api"); -ENTRY(_mainCRTStartup) -SECTIONS -{ - .text __image_base__ + __section_alignment__ : - { - *(.init) - *(.text) - *(SORT(.text$*)) - *(.glue_7t) - *(.glue_7) - ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; - LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); - ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; - LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); - *(.fini) - /* ??? Why is .gcc_exc here? */ - *(.gcc_exc) - PROVIDE (etext = .); - *(.gcc_except_table) - } - /* The Cygwin32 library uses a section to avoid copying certain data - on fork. This used to be named ".data". The linker used - to include this between __data_start__ and __data_end__, but that - breaks building the cygwin32 dll. Instead, we name the section - ".data_cygwin_nocopy" and explictly include it after __data_end__. */ - .data BLOCK(__section_alignment__) : - { - __data_start__ = . ; - *(.data) - *(.data2) - *(SORT(.data$*)) - *(.rdata) - *(SORT(.rdata$*)) - *(.eh_frame) - ___RUNTIME_PSEUDO_RELOC_LIST__ = .; - __RUNTIME_PSEUDO_RELOC_LIST__ = .; - *(.rdata_runtime_pseudo_reloc) - ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; - __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; - __data_end__ = . ; - *(.data_cygwin_nocopy) - } - .rdata BLOCK(__section_alignment__) : - { - } - .pdata BLOCK(__section_alignment__) : - { - *(.pdata) - } - .bss BLOCK(__section_alignment__) : - { - __bss_start__ = . ; - *(.bss) - *(COMMON) - __bss_end__ = . ; - } - .edata BLOCK(__section_alignment__) : - { - *(.edata) - } - /DISCARD/ : - { - *(.debug$S) - *(.debug$T) - *(.debug$F) - *(.drectve) - } - .idata BLOCK(__section_alignment__) : - { - /* This cannot currently be handled with grouped sections. - See pe.em:sort_sections. */ - SORT(*)(.idata$2) - SORT(*)(.idata$3) - /* These zeroes mark the end of the import list. */ - LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); - SORT(*)(.idata$4) - SORT(*)(.idata$5) - SORT(*)(.idata$6) - SORT(*)(.idata$7) - } - .CRT BLOCK(__section_alignment__) : - { - ___crt_xc_start__ = . ; - *(SORT(.CRT$XC*)) /* C initialization */ - ___crt_xc_end__ = . ; - ___crt_xi_start__ = . ; - *(SORT(.CRT$XI*)) /* C++ initialization */ - ___crt_xi_end__ = . ; - ___crt_xl_start__ = . ; - *(SORT(.CRT$XL*)) /* TLS callbacks */ - /* ___crt_xl_end__ is defined in the TLS Directory support code */ - ___crt_xp_start__ = . ; - *(SORT(.CRT$XP*)) /* Pre-termination */ - ___crt_xp_end__ = . ; - ___crt_xt_start__ = . ; - *(SORT(.CRT$XT*)) /* Termination */ - ___crt_xt_end__ = . ; - } - .tls BLOCK(__section_alignment__) : - { - ___tls_start__ = . ; - *(.tls) - *(.tls$) - *(SORT(.tls$*)) - ___tls_end__ = . ; - } - .endjunk BLOCK(__section_alignment__) : - { - /* end is deprecated, don't use it */ - PROVIDE (end = .); - PROVIDE ( _end = .); - __end__ = .; - } - .rsrc BLOCK(__section_alignment__) : - { - *(.rsrc) - *(SORT(.rsrc$*)) - } - .reloc BLOCK(__section_alignment__) : - { - *(.reloc) - } - .stab BLOCK(__section_alignment__) (NOLOAD) : - { - *(.stab) - } - .stabstr BLOCK(__section_alignment__) (NOLOAD) : - { - *(.stabstr) - } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section. Unlike other targets that fake this by putting the - section VMA at 0, the PE format will not allow it. */ - /* DWARF 1.1 and DWARF 2. */ - .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_aranges) - } - .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_pubnames) - } - /* DWARF 2. */ - .debug_info BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_info) *(.gnu.linkonce.wi.*) - } - .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_abbrev) - } - .debug_line BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_line) - } - .debug_frame BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_frame) - } - .debug_str BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_str) - } - .debug_loc BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_loc) - } - .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_macinfo) - } - /* SGI/MIPS DWARF 2 extensions. */ - .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_weaknames) - } - .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_funcnames) - } - .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_typenames) - } - .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_varnames) - } - /* DWARF 3. */ - .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : - { - *(.debug_ranges) - } -} -''') - script.close() - return(ld_script) - - -class loggedSpawn: - def __init__(self, env, logfile, longarg, info): - # save the spawn system - self.env = env - self.logfile = logfile - # clear the logfile (it may not exist) - if logfile != '': - # this will overwrite existing content. - writeToFile(logfile, info, append=False) - # - self.longarg = longarg - # get hold of the old spawn? (necessary?) - self._spawn = env['SPAWN'] - - # define new SPAWN - def spawn(self, sh, escape, cmd, args, spawnenv): - # get command line - newargs = ' '.join(map(escape, args[1:])) - cmdline = cmd + " " + newargs - # - # if log is not empty, write to it - if self.logfile != '': - # this tend to be slow (?) but ensure correct output - # Note that cmdline may be long so I do not escape it - try: - # since this is not an essential operation, proceed if things go wrong here. - writeToFile(self.logfile, cmd + " " + ' '.join(args[1:]) + '\n', append=True) - except: - print "Warning: can not write to log file ", self.logfile - # - # if the command is not too long, use the old - if not self.longarg or len(cmdline) < 8000: - exit_code = self._spawn(sh, escape, cmd, args, spawnenv) - else: - sAttrs = win32security.SECURITY_ATTRIBUTES() - StartupInfo = win32process.STARTUPINFO() - for var in spawnenv: - spawnenv[var] = spawnenv[var].encode('ascii', 'replace') - # check for any special operating system commands - if cmd == 'del': - for arg in args[1:]: - win32file.DeleteFile(arg) - exit_code = 0 - else: - # otherwise execute the command. - hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(None, cmdline, None, None, 1, 0, spawnenv, None, StartupInfo) - win32event.WaitForSingleObject(hProcess, win32event.INFINITE) - exit_code = win32process.GetExitCodeProcess(hProcess) - win32file.CloseHandle(hProcess); - win32file.CloseHandle(hThread); - return exit_code - - -def setLoggedSpawn(env, logfile = '', longarg=False, info=''): - ''' This function modify env and allow logging of - commands to a logfile. If the argument is too long - a win32 spawn will be used instead of the system one - ''' - if longarg: - import win32file - import win32event - import win32process - import win32security - import string - # - # create a new spwn object - ls = loggedSpawn(env, logfile, longarg, info) - # replace the old SPAWN by the new function - env['SPAWN'] = ls.spawn - - -## def CheckPython(context, minver): -## context.Message('Checking for Python >= %s...' % '.'.join(str(x) for x in minver)) -## try: -## python = context.env['PYTHON'] -## except KeyError: -## try: -## python = os.environ['PYTHON'] -## except KeyError: -## python = WhereIs("python") -## if not python: -## python = python = WhereIs("python%i.%i" % (minver[0], minver[1])) -## minverhex = 0 -## minver = list(minver) + [0, 0, 0, 0] -## for i in xrange(0, 4): -## minverhex = (minverhex << 8) + minver[i] -## prog = "import sys; sys.exit(sys.hexversion >= %s)" % minverhex -## if python is None: -## python = 'python' -## try: -## result = Popen([python, "-c", prog]).wait() -## except OSError: -## context.Result(False) -## return False -## context.Result(result) -## if result: -## context.env.Replace(PYTHON=python) -## proc = Popen([python, "-c", "import sys; print sys.version[:3]"], stdout=PIPE) -## pyver = proc.communicate()[0].rstrip() -## context.env.Replace(PYTHON_VERSION=pyver) -## context.env.Replace(pythondir="$prefix/lib/python$PYTHON_VERSION/site-packages") -## context.env.Replace(pyexecdir="${exec_prefix}/lib/python$PYTHON_VERSION/site-packages") -## return result -## -## def DistSources(env, node): -## env.DistFiles(_get_sources(env, node)) -## -## def DistFiles(env, files): -## assert isinstance(files, (list, tuple)) -## DISTFILES = [env.File(fname) for fname in files] -## env.AppendUnique(DISTFILES=DISTFILES) -## -## -## def make_distdir(target=None, source=None, env=None): -## distdir = env.subst('$DISTDIR') -## Execute(Delete(distdir)) -## Execute(Mkdir(distdir)) -## for fnode in env["DISTFILES"]: -## dirname, fname = os.path.split(str(fnode)) -## if dirname: -## distdirname = os.path.join(distdir, dirname) -## if not os.path.exists(distdirname): -## Execute(Mkdir(distdirname)) -## Execute(Copy(os.path.join(distdir, dirname, fname), str(fnode))) -## -## def make_dist(target=None, source=None, env=None): -## return Popen([env['TAR'], "-zcf", -## env.subst("${PACKAGE}-${VERSION}.tar.gz"), -## env.subst('$DISTDIR')]).wait() -## -## def make_distcheck(target=None, source=None, env=None): -## distdir = env.subst('$DISTDIR') -## distcheckinstdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-instdir-')) -## distcheckdestdir = tempfile.mkdtemp('', env.subst('${PACKAGE}-${VERSION}-destdir-')) -## instdirs = [os.path.join(distcheckinstdir, d) for d in -## 'lib', 'share', 'bin', 'include'] -## for dir_ in instdirs: -## Execute(Mkdir(dir_)) -## -## cmd = env.subst("cd $DISTDIR && scons DESTDIR=%s prefix=%s" -## " && scons check && scons install") %\ -## (os.path.join(distcheckdestdir, ''), distcheckinstdir) -## status = Popen(cmd, shell=True).wait() -## if status: -## return status -## ## Check that inst dirs are empty (to catch cases of $DESTDIR not being honored -## for dir_ in instdirs: -## if os.listdir(dir_): -## raise SCons.Errors.BuildError(target, "%s not empy" % dir_) -## ## Check that something inside $DESTDIR was installed -## dir_ = os.path.join(distcheckdestdir, distcheckinstdir) -## if not os.path.exists(dir_): -## raise SCons.Errors.BuildError(target, "%s does not exist" % dir_) -## Execute(Delete(distcheckinstdir)) -## Execute(Delete(distcheckdestdir)) -## Execute(Delete(distdir)) -## -## def InstallWithDestDir(self, dir_, source): -## dir_ = '${DESTDIR}' + str(dir_) -## return SConsEnvironment.Install(self, dir_, source) -## -## -## def InstallAsWithDestDir(self, target, source): -## target = '${DESTDIR}' + str(target) -## return SConsEnvironment.InstallAs(self, target, source) -## -## def generate(env): -## env.EnsureSConsVersion(0, 96, 91) -## -## opts = Options(['options.cache'], ARGUMENTS) -## opts.Add(PathOption('prefix', 'Installation prefix', '/usr/local')) -## opts.Add(PathOption('exec_prefix', 'Installation prefix blah blah', -## '$prefix')) -## opts.Add(PathOption('libdir', -## 'Installation prefix for architecture dependent files', '$prefix/lib')) -## opts.Add(PathOption('includedir', -## 'Installation prefix for C header files', '$prefix/include')) -## opts.Add(PathOption('datadir', -## 'Installation prefix for architecture independent files', '$prefix/share')) -## opts.Add(PathOption('bindir', 'Installation prefix for programs', '$prefix/bin')) -## opts.Add(PathOption('DESTDIR', 'blah blah', None)) -## opts.Update(env) -## opts.Save('options.cache', env) -## SConsEnvironment.Help(env, opts.GenerateHelpText(env)) -## -## env.Append(CPPFLAGS=r' -DVERSION=\"$VERSION\"') -## env.Append(CCFLAGS=ARGUMENTS.get('CCFLAGS', '-g -O2')) -## -## env['GNOME_TESTS'] = dict(CheckPython=CheckPython, -## CheckPythonHeaders=CheckPythonHeaders, -## PkgCheckModules=PkgCheckModules) -## -## SConsEnvironment.DistSources = DistSources -## SConsEnvironment.DistFiles = DistFiles -## env['DISTDIR'] = "${PACKAGE}-${VERSION}" -## -## #env.Command(env.Dir("$DISTDIR"), None, make_distdir) -## -## distdir_alias = env.Alias("distdir", None, make_distdir) -## dist_alias = env.Alias("dist", None, make_dist) -## env.Depends(dist_alias, distdir_alias) -## distcheck_alias = env.Alias("distcheck", None, make_distcheck) -## env.Depends(distcheck_alias, distdir_alias) -## env.AlwaysBuild(env.Alias('check')) -## -## #env['TARFLAGS'] ='-c -z' -## #env['TARSUFFIX'] = '.tar.gz' -## #tar = env.Tar('${PACKAGE}-${VERSION}.tar.gz', "${DISTDIR}") -## #env.Depends(tar, distdir_alias) -## #print env['DEFAULT_TARGETS'] -## -## #env.Depends(distdir_alias, "${DISTFILES}") -## #env.Alias('dist', tar) -## env.AlwaysBuild('dist') -## env.AlwaysBuild('distdir') -## env.AlwaysBuild('distcheck') -## env.DistFiles(['SConstruct', 'scons/gnome.py']) -## -## env['BUILDERS']['EnvSubstFile'] = SCons.Builder.Builder(action=env_subst) -## -## SConsEnvironment.PythonByteCompile = env.Action(byte_compile_python) -## -## env.Install = new.instancemethod(InstallWithDestDir, env, env.__class__) -## env.InstallAs = new.instancemethod(InstallAsWithDestDir, env, env.__class__) -## -## -## - diff --git a/src/SConscript b/src/SConscript index 4e90038cf0..88fa708dd7 100644 --- a/src/SConscript +++ b/src/SConscript @@ -142,6 +142,7 @@ lyx_source = Split(''' vc-backend.C version.C vspace.C + main.C ''') if env.has_key('USE_ASPELL') and env['USE_ASPELL']: @@ -151,22 +152,14 @@ elif env.has_key('USE_PSPELL') and env['USE_PSPELL']: elif env.has_key('USE_ISPELL') and env['USE_ISPELL']: lyx_source += ['ispell.C'] -# -# Create a static library for this directory as well -# -lyx_base = env.StaticLibrary( - target = '$LOCALLIBPATH/lyx_base', - source = lyx_source -) # # Build lyx with given frontend # lyx = env.Program( target = 'lyx', - source = ['main.C'], + source = lyx_source, LIBS = [ - 'lyx_base', 'mathed', 'insets', 'frontends', diff --git a/src/frontends/qt4/SConscript b/src/frontends/qt4/SConscript index cdec36773a..be55546012 100644 --- a/src/frontends/qt4/SConscript +++ b/src/frontends/qt4/SConscript @@ -21,7 +21,7 @@ qtenv = env.Copy() # NOTE: I have to patch qt4.py since it does not automatically # process .C file!!! (add to cxx_suffixes ) # -qtenv.Tool('qt4', ['$TOP_SRC_DIR']) +qtenv.Tool('qt4', ['$TOP_SRC_DIR/config']) qtenv.EnableQt4Modules(env['QT_LIB'], debug = False) qtenv.Append(CPPPATH = [ @@ -133,7 +133,6 @@ moc_files = Split(''' QBoxDialog.C QBranchDialog.C QBranches.C - QBrowseBox.C QChangesDialog.C QCharacterDialog.C QCitationDialog.C @@ -244,9 +243,7 @@ source_files = Split(''' checkedwidgets.C lyx_gui.C lcolorcache.C - panelstack.h panelstack.C - qcoloritem.C qfontexample.C qfont_loader.C qfont_metrics.C