From 870ceb0a8048ffcdece85ee6f9603081808e6505 Mon Sep 17 00:00:00 2001 From: Joost Verburg Date: Wed, 25 Jul 2007 19:14:23 +0000 Subject: [PATCH] embed manifest file of LyX itself git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@19214 a592a061-630c-0410-9148-cb99ea01b6c8 --- development/scons/SConstruct | 4114 +++++++++++++++++----------------- 1 file changed, 2055 insertions(+), 2059 deletions(-) diff --git a/development/scons/SConstruct b/development/scons/SConstruct index ebcb439e43..b071a21288 100644 --- a/development/scons/SConstruct +++ b/development/scons/SConstruct @@ -1,2059 +1,2055 @@ -# vi:filetype=python:expandtab:tabstop=4:shiftwidth=4 -# -# file SConstruct -# -# 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 is a scons based building system for lyx, please refer -# to INSTALL.scons for detailed instructions. -# - -import os, sys, copy, cPickle, glob, time - -# scons_utils.py defines a few utility function -sys.path.append('config') -import scons_utils as utils -# import all file lists -from scons_manifest import * - -#---------------------------------------------------------- -# Required runtime environment -#---------------------------------------------------------- - -# scons asks for 1.5.2, lyx requires 2.3 -EnsurePythonVersion(2, 3) -# Please use at least 0.96.92 (not 0.96.1) -EnsureSConsVersion(0, 96) -# also check for minor version number for scons 0.96 -from SCons import __version__ -version = map(int, __version__.split('.')) -if version[0] == 0 and version[1] == 96 and version[2] < 92: - print "Scons >= 0.96.92 is required." - Exit(1) - -# determine where I am ... -# -from SCons.Node.FS import default_fs -# default_fs.SConstruct_dir is where SConstruct file is located. -scons_dir = default_fs.SConstruct_dir.path -# get the ../.. of scons_dir -top_src_dir = os.path.split(os.path.split(default_fs.SConstruct_dir.abspath)[0])[0] - - -#---------------------------------------------------------- -# Global definitions -#---------------------------------------------------------- - -# some global settings -# -# get version number from configure.ac so that JMarc does -# not have to change SConstruct during lyx release -package_version = utils.getVerFromConfigure(top_src_dir) -package_cygwin_version = '%s-1' % package_version -boost_version = ['1_32'] - -if 'svn' in package_version: - devel_version = True - default_build_mode = 'debug' -else: - devel_version = False - default_build_mode = 'release' - -package = 'lyx' -package_bugreport = 'lyx-devel@lists.lyx.org' -package_name = 'LyX' -package_tarname = 'lyx' -package_string = '%s %s' % (package_name, package_version) - -# various cache/log files -default_log_file = 'scons_lyx.log' -opt_cache_file = 'opt.cache' - - -#---------------------------------------------------------- -# platform dependent settings -#---------------------------------------------------------- - -if os.name == 'nt': - platform_name = 'win32' - default_prefix = 'c:/program files/lyx' - default_with_x = False - default_packaging_method = 'windows' -elif os.name == 'posix' and sys.platform != 'cygwin': - platform_name = sys.platform - default_prefix = '/usr/local' - default_with_x = True - default_packaging_method = 'posix' -elif os.name == 'posix' and sys.platform == 'cygwin': - platform_name = 'cygwin' - default_prefix = '/usr' - default_with_x = True - default_packaging_method = 'posix' -elif os.name == 'darwin': - platform_name = 'macosx' - # FIXME: macOSX default prefix? - default_prefix = '.' - default_with_x = False - default_packaging_method = 'macosx' -else: # unsupported system, assume posix behavior - platform_name = 'others' - default_prefix = '.' - default_with_x = True - default_packaging_method = 'posix' - -#--------------------------------------------------------- -# Handling options -#---------------------------------------------------------- -# -# You can set perminant default values in config.py -if os.path.isfile('config.py'): - print "Getting options from config.py..." - print open('config.py').read() - -opts = Options(['config.py']) -opts.AddOptions( - # frontend - EnumOption('frontend', 'Main GUI', 'qt2', - allowed_values = ('qt2',) ), - # debug or release build - EnumOption('mode', 'Building method', default_build_mode, - allowed_values = ('debug', 'release') ), - # boost libraries - EnumOption('boost', - 'Use included, system boost library, or try sytem boost first.', - 'auto', allowed_values = ( - 'auto', # detect boost, if not found, use included - 'included', # always use included boost - 'system', # always use system boost, fail if can not find - ) ), - # - EnumOption('gettext', - 'Use included, system gettext library, or try sytem gettext first', - 'auto', allowed_values = ( - 'auto', # detect gettext, if not found, use included - 'included', # always use included gettext - 'system', # always use system gettext, fail if can not find - ) ), - # - EnumOption('spell', 'Choose spell checker to use.', 'auto', - allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ), - # packaging method - EnumOption('packaging', 'Packaging method to use.', default_packaging_method, - allowed_values = ('windows', 'posix', 'macosx')), - # - BoolOption('fast_start', 'This option is obsolete.', False), - # No precompiled header support (too troublesome to make it work for msvc) - # BoolOption('pch', 'Whether or not use pch', False), - # enable assertion, (config.h has ENABLE_ASSERTIOS - BoolOption('assertions', 'Use assertions', True), - # enable warning, (config.h has WITH_WARNINGS) - # default to False since MSVC does not have #warning - BoolOption('warnings', 'Use warnings', False), - # config.h define _GLIBCXX_CONCEPT_CHECKS - # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS - BoolOption('concept_checks', 'Enable concept checks', True), - # - BoolOption('nls', 'Whether or not use native language support', True), - # - BoolOption('profiling', 'Whether or not enable profiling', False), - # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC - BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False), - # using x11? - BoolOption('X11', 'Use x11 windows system', default_with_x), - # use MS VC++ to build lyx - BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None), - # - PathOption('qt_dir', 'Path to qt directory', None), - # - PathOption('qt_inc_path', 'Path to qt include directory', None), - # - PathOption('qt_lib_path', 'Path to qt library directory', None), - # extra include and libpath - PathOption('extra_inc_path', 'Extra include path', None), - # - PathOption('extra_lib_path', 'Extra library path', None), - # - PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None), - # - PathOption('extra_inc_path1', 'Extra include path', None), - # - PathOption('extra_lib_path1', 'Extra library path', None), - # rebuild only specifed, comma separated targets - ('rebuild', '''rebuild only specifed, comma separated targets. - yes or all (default): rebuild everything - no or none: rebuild nothing (usually used for installation) - comp1,comp2,...: rebuild specified targets''', None), - # can be set to a non-existing directory - ('prefix', 'install architecture-independent files in PREFIX', default_prefix), - # build directory, will use $mode if not set - ('build_dir', 'Build directory', None), - # version suffix - ('version_suffix', 'install lyx as lyx-suffix', None), - # how to load options - ('load_option', '''load option from previous scons run. option can be - yes (default): load all options - no: do not load any option - opt1,opt2: load specified options - -opt1,opt2: load all options other than specified ones''', 'yes'), - # - ('optimization', 'optimization CCFLAGS option.', None), - # - PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None), - # log file - ('logfile', 'save commands (not outputs) to logfile', default_log_file), - # provided for backward compatibility - ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None), - # environment variable can be set as options. - ('DESTDIR', 'install to DESTDIR', None), - ('CC', 'replace default $CC', None), - ('LINK', 'replace default $LINK', None), - ('CPP', 'replace default $CPP', None), - ('CXX', 'replace default $CXX', None), - ('CXXCPP', 'replace default $CXXCPP', None), - ('CCFLAGS', 'replace default $CCFLAGS', None), - ('CPPFLAGS', 'replace default $CPPFLAGS', None), - ('LINKFLAGS', 'replace default $LINKFLAGS', None), -) - -# allowed options -all_options = [x.key for x in opts.options] - -# copied from SCons/Options/BoolOption.py -# We need to use them before a boolean ARGUMENTS option is available -# in env as bool. -true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' ) -false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none') - -if ARGUMENTS.has_key('fast_start'): - print 'fast_start option is obsolete' - -# if load_option=yes (default), load saved comand line options -# -# This option can take value yes/no/opt1,opt2/-opt1,opt2 -# and tries to be clever in choosing options to load -if (not ARGUMENTS.has_key('load_option') or \ - ARGUMENTS['load_option'] not in false_strings) \ - and os.path.isfile(opt_cache_file): - cache_file = open(opt_cache_file) - opt_cache = cPickle.load(cache_file) - cache_file.close() - # import cached options, but we should ignore qt_dir when frontend changes - if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \ - and ARGUMENTS['frontend'] != opt_cache['frontend'] \ - and opt_cache.has_key('qt_dir'): - opt_cache.pop('qt_dir') - # and we do not cache some options (dest_dir is obsolete) - for arg in ['load_option', 'dest_dir']: - if opt_cache.has_key(arg): - opt_cache.pop(arg) - # remove obsolete cached keys (well, SConstruct is evolving. :-) - for arg in opt_cache.keys(): - if arg not in all_options: - print 'Option %s is obsolete, do not load it' % arg - opt_cache.pop(arg) - # now, if load_option=opt1,opt2 or -opt1,opt2 - if ARGUMENTS.has_key('load_option') and \ - ARGUMENTS['load_option'] not in true_strings + false_strings: - # if -opt1,opt2 is specified, do not load these options - if ARGUMENTS['load_option'][0] == '-': - for arg in ARGUMENTS['load_option'][1:].split(','): - if opt_cache.has_key(arg): - opt_cache.pop(arg) - # if opt1,opt2 is specified, only load specified options - else: - args = ARGUMENTS['load_option'].split(',') - for arg in opt_cache.keys(): - if arg not in args: - opt_cache.pop(arg) - # now restore options as if entered from command line - for key in opt_cache.keys(): - if not ARGUMENTS.has_key(key): - ARGUMENTS[key] = opt_cache[key] - print "Restoring cached option %s=%s" % (key, ARGUMENTS[key]) - print - -# check if there is unused (or misspelled) argument -for arg in ARGUMENTS.keys(): - if arg not in all_options: - import textwrap - print "Unknown option '%s'... exiting." % arg - print - print "Available options are (check 'scons -help' for details):" - print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options))) - Exit(1) - -# save options used -cache_file = open(opt_cache_file, 'w') -cPickle.dump(ARGUMENTS, cache_file) -cache_file.close() - - -#--------------------------------------------------------- -# Setting up environment -#--------------------------------------------------------- - -# I do not really like ENV=os.environ, but you may add it -# here if you experience some environment related problem -env = Environment(options = opts) - -# set individual variables since I do not really like ENV = os.environ -env['ENV']['PATH'] = os.environ.get('PATH') -env['ENV']['HOME'] = os.environ.get('HOME') -# these are defined for MSVC -env['ENV']['LIB'] = os.environ.get('LIB') -env['ENV']['INCLUDE'] = os.environ.get('INCLUDE') - -# for simplicity, use var instead of env[var] -frontend = env['frontend'] -prefix = env['prefix'] -mode = env['mode'] - -if platform_name == 'win32': - if env.has_key('use_vc'): - use_vc = env['use_vc'] - if WhereIs('cl.exe') is None: - print "cl.exe is not found. Are you using the MSVC environment?" - Exit(2) - elif WhereIs('cl.exe') is not None: - use_vc = True - else: - use_vc = False -else: - use_vc = False - -# lyx will be built to $build/build_dir so it is possible -# to build multiple build_dirs using the same source -# $mode can be debug or release -if env.has_key('build_dir') and env['build_dir'] is not None: - # create the directory if needed - if not os.path.isdir(env['build_dir']): - try: - os.makedirs(env['build_dir']) - except: - pass - if not os.path.isdir(env['build_dir']): - print 'Can not create directory', env['build_dir'] - Exit(3) - env['BUILDDIR'] = env['build_dir'] -else: - # Determine the name of the build $mode - env['BUILDDIR'] = '#' + mode - -# all built libraries will go to build_dir/libs -# (This is different from the make file approach) -env['LOCALLIBPATH'] = '$BUILDDIR/libs' -env.AppendUnique(LIBPATH = ['$LOCALLIBPATH']) - - -# Here is a summary of variables defined in env -# 1. defined options -# 2. undefined options with a non-None default value -# 3. compiler commands and flags like CCFLAGS. -# MSGFMT used to process po files -# 4. Variables that will be used to replace variables in some_file.in -# src/support/package.C.in: -# TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX -# lib/lyx2lyx/lyx2lyx_version.py.in -# PACKAGE_VERSION -# src/version.C.in -# PACKAGE_VERSION, LYX_DATE, VERSION_INFO - -# full path name is used to build msvs project files -# and to replace TOP_SRCDIR in package.C -env['TOP_SRCDIR'] = Dir(top_src_dir).abspath -# needed by src/version.C.in => src/version.C -env['PACKAGE_VERSION'] = package_version -env['LYX_DATE'] = time.asctime() - -# determine share_dir etc -packaging_method = env.get('packaging') -if packaging_method == 'windows': - share_dir = 'Resources' - man_dir = 'Resources/man/man1' - locale_dir = 'Resources/locale' -else: - share_dir = 'share/lyx' - locale_dir = 'share/locale' - if platform_name == 'cygwin': - man_dir = 'share/man/man1' - else: - man_dir = 'man/man1' - -# program suffix: can be yes, or a string -if env.has_key('version_suffix'): - if env['version_suffix'] in true_strings: - program_suffix = package_version - elif env['version_suffix'] in false_strings: - program_suffix = '' - else: - program_suffix = env['version_suffix'] -else: - program_suffix = '' -# used by package.C.in -env['PROGRAM_SUFFIX'] = program_suffix - -# whether or not add suffix to file and directory names -add_suffix = packaging_method != 'windows' -# LYX_DIR are different (used in package.C.in) -if add_suffix: - env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath -else: - env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath -# we need absolute path for package.C -env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath - - -#--------------------------------------------------------- -# Setting building environment (Tools, compiler flags etc) -#--------------------------------------------------------- - -# Since Tool('mingw') will reset CCFLAGS etc, this should be -# done before getEnvVariable -if platform_name == 'win32': - if use_vc: - env.Tool('msvc') - env.Tool('mslink') - else: - env.Tool('mingw') - env.AppendUnique(CPPPATH = ['#c:/MinGW/include']) - # fix a scons winres bug (there is a missing space between ${RCINCPREFIX} and ${SOURCE.dir} - # in version 0.96.93 - env['RCCOM'] = '$RC $_CPPDEFFLAGS $RCINCFLAGS ${RCINCPREFIX} ${SOURCE.dir} $RCFLAGS -i $SOURCE -o $TARGET' - - -# we differentiate between hard-coded options and default options -# hard-coded options are required and will always be there -# default options can be replaced by enviromental variables or command line options -CCFLAGS_required = [] -LINKFLAGS_required = [] -CCFLAGS_default = [] - -# under windows, scons is confused by .C/.c and uses gcc instead of -# g++. I am forcing the use of g++ here. This is expected to change -# after lyx renames all .C files to .cpp -# -# save the old c compiler and CCFLAGS (used by libintl) -C_COMPILER = env.subst('$CC') -C_CCFLAGS = env.subst('$CCFLAGS').split() -# if we use ms vc, the commands are fine (cl.exe and link.exe) -if use_vc: - # /TP treat all source code as C++ - # C4819: The file contains a character that cannot be represented - # in the current code page (number) - # C4996: foo was decleared deprecated - CCFLAGS_required.extend(['/TP', '/EHsc']) - if mode == 'debug': - CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MDd']) - # the flags are also needed in C mode (for intl lib) - C_CCFLAGS.extend(['/wd4819', '/wd4996', '/nologo', '/MDd']) - else: - CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MD']) - C_CCFLAGS.extend(['/wd4819', '/wd4996', '/nologo', '/MD']) -else: - if env.has_key('CXX') and env['CXX']: - env['CC'] = env.subst('$CXX') - env['LINK'] = env.subst('$CXX') - else: - env['CC'] = 'g++' - env['LINK'] = 'g++' - -# for debug/release mode -if env.has_key('optimization') and env['optimization'] is not None: - # if user supplies optimization flags, use it anyway - CCFLAGS_required.extend(env['optimization'].split()) - # and do not use default - set_default_optimization_flags = False -else: - set_default_optimization_flags = True - -if mode == 'debug': - if use_vc: - CCFLAGS_required.append('/Zi') - LINKFLAGS_required.extend(['/debug', '/map']) - else: - CCFLAGS_required.append('-g') - CCFLAGS_default.append('-O') -elif mode == 'release' and set_default_optimization_flags: - if use_vc: - CCFLAGS_default.append('/O2') - else: - CCFLAGS_default.append('-O2') - -# msvc uses separate tools for profiling -if env.has_key('profiling') and env['profiling']: - if use_vc: - print 'Visual C++ does not use profiling options' - else: - CCFLAGS_required.append('-pg') - LINKFLAGS_required.append('-pg') - -if env.has_key('warnings') and env['warnings']: - if use_vc: - CCFLAGS_default.append('/W2') - else: - # Note: autotools detect gxx version and pass -W for 3.x - # and -Wextra for other versions of gcc - CCFLAGS_default.append('-Wall') - -# Now, set the variables as follows: -# 1. if command line option exists: replace default -# 2. then if s envronment variable exists: replace default -# 3. set variable to required + default -def setEnvVariable(env, name, required = None, default = None, split = True): - ''' env: environment to set variable - name: variable - required: hardcoded options - default: default options that can be replaced by command line or - environment variables - split: whether or not split obtained variable like '-02 -g' - ''' - # 1. ARGUMENTS is already set to env[name], override default. - if ARGUMENTS.has_key(name): - # env[name] may be rewritten when building tools are reloaded - # if that is the case, commandline option will override it. - env[name] = ARGUMENTS[name] - default = None - # then use environment default - elif os.environ.has_key(name): - print "Acquiring variable %s from system environment: %s" % (name, os.environ[name]) - default = os.environ[name] - if split: - default = default.split() - # the real value should be env[name] + default + required - if split: - value = [] - if env.has_key(name): - value = str(env[name]).split() - if required is not None: - value += required - if default is not None: - value += default - else: - value = "" - if env.has_key(name): - value = str(env[name]) - if required is not None: - value += " " + required - if default is not None: - value += " " + default - env[name] = value - # print name, env[name] - -setEnvVariable(env, 'DESTDIR', split=False) -setEnvVariable(env, 'CC') -setEnvVariable(env, 'LINK') -setEnvVariable(env, 'CPP') -setEnvVariable(env, 'CXX') -setEnvVariable(env, 'CXXCPP') -setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default) -setEnvVariable(env, 'CXXFLAGS') -setEnvVariable(env, 'CPPFLAGS') -setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required) - -# if DESTDIR is not set... -if env.has_key('dest_dir'): - print "This option is obsolete. Please use DESTDIR instead." - env['DESTDIR'] = env['dest_dir'] - - -#--------------------------------------------------------- -# Frontend related variables (QTDIR etc) -#--------------------------------------------------------- - -if env.has_key('qt_dir') and env['qt_dir']: - env['QTDIR'] = env['qt_dir'] -elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')): - env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3') - -# if there is a valid QTDIR, set path for lib and bin directories -if env.has_key('QTDIR'): - # add path to the qt tools - if os.path.isdir(os.path.join(env['QTDIR'], 'lib')): - env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')]) - # set environment so that moc etc can be found even if its path is not set properly - if os.path.isdir(os.path.join(env['QTDIR'], 'bin')): - os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin') - env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin')) - -# frontend name is qt2, but we are looking for qt3 libs -frontend_lib = 'qt3' -if env.has_key('qt_lib_path') and env['qt_lib_path']: - qt_lib_path = env.subst('$qt_lib_path') -elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')): - qt_lib_path = env.subst('$QTDIR/lib') -# this is the path for cygwin. -elif os.path.isdir(os.path.join('/usr/lib/', frontend_lib, 'lib')): - qt_lib_path = '/usr/lib/%s/lib' % frontend_lib -else: - print "Qt library directory is not found. Please specify it using qt_lib_path" - Exit(1) -env.AppendUnique(LIBPATH = [qt_lib_path]) -# qt4 seems to be using pkg_config -env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path) - -if env.has_key('qt_inc_path') and env['qt_inc_path']: - qt_inc_path = env['qt_inc_path'] -elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')): - qt_inc_path = '$QTDIR/include' -# this is the path for cygwin. -elif os.path.isdir('/usr/include/' + frontend_lib): - qt_inc_path = '/usr/include/' + frontend_lib -else: - print "Qt include directory not found. Please specify it using qt_inc_path" - Exit(1) -# Note that this CPPPATH is for testing only -# it will be removed before calling SConscript -env['CPPPATH'] = [qt_inc_path] - -# -# extra_inc_path and extra_lib_path -# -extra_inc_paths = [] -if env.has_key('extra_inc_path') and env['extra_inc_path']: - extra_inc_paths.append(env['extra_inc_path']) -if env.has_key('extra_lib_path') and env['extra_lib_path']: - env.AppendUnique(LIBPATH = [env['extra_lib_path']]) -if env.has_key('extra_inc_path1') and env['extra_inc_path1']: - extra_inc_paths.append(env['extra_inc_path1']) -if env.has_key('extra_lib_path1') and env['extra_lib_path1']: - env.AppendUnique(LIBPATH = [env['extra_lib_path1']]) -if env.has_key('extra_bin_path') and env['extra_bin_path']: - # only the first one is needed (a scons bug?) - os.environ['PATH'] += os.pathsep + env['extra_bin_path'] - env.PrependENVPath('PATH', env['extra_bin_path']) -# extra_inc_paths will be used later by intlenv etc -env.AppendUnique(CPPPATH = extra_inc_paths) - - -#---------------------------------------------------------- -# Autoconf business -#---------------------------------------------------------- - -conf = Configure(env, - custom_tests = { - 'CheckPkgConfig' : utils.checkPkgConfig, - 'CheckPackage' : utils.checkPackage, - 'CheckMkdirOneArg' : utils.checkMkdirOneArg, - 'CheckSelectArgType' : utils.checkSelectArgType, - 'CheckBoostLibraries' : utils.checkBoostLibraries, - 'CheckCommand' : utils.checkCommand, - 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd, - 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES, - 'CheckIconvConst' : utils.checkIconvConst, - } -) - -# pkg-config? (if not, we use hard-coded options) -if conf.CheckPkgConfig('0.15.0'): - env['HAS_PKG_CONFIG'] = True -else: - print 'pkg-config >= 0.1.50 is not found' - env['HAS_PKG_CONFIG'] = False - -# zlib? This is required. -if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \ - or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')): - print 'Did not find zdll.lib or zlib.h, exiting!' - Exit(1) - -# -# qt3 does not use pkg_config -if frontend == 'qt2': - # windows lib name is qt-mt3 - if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \ - and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'): - print 'Did not find qt libraries, exiting!' - Exit(1) - -# now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file -if use_vc: - if mode == 'debug': - manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest') - else: - manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest') - if os.path.isfile(manifest): - env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest] - -# check socket libs -socket_libs = [] -if conf.CheckLib('socket'): - socket_libs.append('socket') -# nsl is the network services library and provides a -# transport-level interface to networking services. -if conf.CheckLib('nsl'): - socket_libs.append('nsl') - -# check available boost libs (since lyx1.4 does not use iostream) -boost_libs = [] -for lib in ['signals', 'regex', 'filesystem', 'iostreams']: - if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)): - boost_libs.append(lib) - -# check boost libraries -boost_opt = ARGUMENTS.get('boost', 'auto') -# check for system boost -lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib'] -inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include'] -# default to $BUILDDIR/libs (use None since this path will be added anyway) -boost_libpath = None -# here I assume that all libraries are in the same directory -if boost_opt == 'included': - boost_libraries = ['included_boost_%s' % x for x in boost_libs] - included_boost = True - env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost' -elif boost_opt == 'auto': - res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug') - # if not found, use local boost - if res[0] is None: - boost_libraries = ['included_boost_%s' % x for x in boost_libs] - included_boost = True - env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost' - else: - included_boost = False - (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res -elif boost_opt == 'system': - res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug') - if res[0] is None: - print "Can not find system boost libraries with version %s " % boost_version - print "Please supply a path through extra_lib_path and try again." - print "Or use boost=included to use included boost libraries." - Exit(2) - else: - included_boost = False - (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res - -if boost_libpath is not None: - env.AppendUnique(LIBPATH = [boost_libpath]) - - -env['ENABLE_NLS'] = env['nls'] - -if not env['ENABLE_NLS']: - intl_libs = [] - included_gettext = False -else: - # check gettext libraries - gettext_opt = ARGUMENTS.get('gettext', 'auto') - # check for system gettext - succ = False - if gettext_opt in ['auto', 'system']: - if conf.CheckLib('intl'): - included_gettext = False - intl_libs = ['intl'] - succ = True - else: # no found - if gettext_opt == 'system': - print "Can not find system gettext library" - print "Please supply a path through extra_lib_path and try again." - print "Or use gettext=included to use included gettext libraries." - Exit(2) - # now, auto and succ = false, or gettext=included - if not succ: - # we do not need to set LIBPATH now. - included_gettext = True - intl_libs = ['included_intl'] - -# -# check for msgfmt command -env['MSGFMT'] = conf.CheckCommand('msgfmt') - -# cygwin packaging requires the binaries to be stripped -if platform_name == 'cygwin': - env['STRIP'] = conf.CheckCommand('strip') - -# check uic and moc commands for qt frontends -if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \ - or conf.CheckCommand('moc') == None): - print 'uic or moc command is not found for frontend', frontend - Exit(1) - -# -# Customized builders -# -# install customized builders -env['BUILDERS']['substFile'] = Builder(action = utils.env_subst) - - -#---------------------------------------------------------- -# Generating config.h -#---------------------------------------------------------- -aspell_lib = 'aspell' -# assume that we use aspell, aspelld compiled for msvc -if platform_name == 'win32' and mode == 'debug' and use_vc: - aspell_lib = 'aspelld' - -# check the existence of config.h -config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h') -boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h') -# -print "Creating %s..." % boost_config_h -# -utils.createConfigFile(conf, - config_file = boost_config_h, - config_pre = '''/* boost/config.h. Generated by SCons. */ - -/* -*- 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 _BOOST_CONFIG_H -#define _BOOST_CONFIG_H -''', - headers = [ - ('ostream', 'HAVE_OSTREAM', 'cxx'), - ('locale', 'HAVE_LOCALE', 'cxx'), - ('sstream', 'HAVE_SSTREAM', 'cxx'), - #('newapis.h', 'HAVE_NEWAPIS_H', 'c'), - ], - custom_tests = [ - (env.has_key('assertions') and env['assertions'], - 'ENABLE_ASSERTIONS', - 'Define if you want assertions to be enabled in the code' - ), - ], - config_post = ''' - -#if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM) -# define USE_BOOST_FORMAT 1 -#else -# define USE_BOOST_FORMAT 0 -#endif - -#if !defined(ENABLE_ASSERTIONS) -# define BOOST_DISABLE_ASSERTS 1 -#endif -#define BOOST_ENABLE_ASSERT_HANDLER 1 - -#define BOOST_DISABLE_THREADS 1 -#define BOOST_NO_WSTRING 1 - -#ifdef __CYGWIN__ -# define BOOST_POSIX 1 -#endif - -#define BOOST_ALL_NO_LIB 1 - -#if defined(HAVE_NEWAPIS_H) -# define WANT_GETFILEATTRIBUTESEX_WRAPPER 1 -#endif - -#endif -''' -) -# -print "\nGenerating %s..." % config_h - -# AIKSAURUS_H_LOCATION -if (conf.CheckCXXHeader("Aiksaurus.h")): - aik_location = '' -elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")): - aik_location = '' -else: - aik_location = '' - -# determine headers to use -spell_opt = ARGUMENTS.get('spell', 'auto') -env['USE_ASPELL'] = False -env['USE_PSPELL'] = False -env['USE_ISPELL'] = False -if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib): - spell_engine = 'USE_ASPELL' -elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'): - spell_engine = 'USE_PSPELL' -elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'): - spell_engine = 'USE_ISPELL' -else: - spell_engine = None - -if spell_engine is not None: - env[spell_engine] = True -else: - if spell_opt == 'auto': - print "Warning: Can not locate any spell checker" - elif spell_opt != 'no': - print "Warning: Can not locate specified spell checker:", spell_opt - Exit(1) - -# check for iconv function/lib -if conf.CheckLib('iconv'): - env['ICONV_LIB'] = 'iconv' - env['HAVE_ICONV'] = True -elif conf.CheckLib('libiconv'): - env['ICONV_LIB'] = 'libiconv' - env['HAVE_ICONV'] = True -elif conf.CheckFunc('iconv_open'): - env['ICONV_LIB'] = None - env['HAVE_ICONV'] = True -else: - env['ICONV_LIB'] = None - env['HAVE_ICONV'] = False - -# check arg types of select function -(select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType() - -# -# create config.h -result = utils.createConfigFile(conf, - config_file = config_h, - config_pre = '''/* config.h. Generated by SCons. */ - -/* -*- 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 -''', - headers = [ - ('io.h', 'HAVE_IO_H', 'c'), - ('limits.h', 'HAVE_LIMITS_H', 'c'), - ('locale.h', 'HAVE_LOCALE_H', 'c'), - ('process.h', 'HAVE_PROCESS_H', 'c'), - ('stdlib.h', 'HAVE_STDLIB_H', 'c'), - ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'), - ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'), - ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'), - ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'), - ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'), - ('unistd.h', 'HAVE_UNISTD_H', 'c'), - ('utime.h', 'HAVE_UTIME_H', 'c'), - ('direct.h', 'HAVE_DIRECT_H', 'c'), - ('istream', 'HAVE_ISTREAM', 'cxx'), - ('ios', 'HAVE_IOS', 'cxx'), - ], - functions = [ - ('open', 'HAVE_OPEN', None), - ('close', 'HAVE_CLOSE', None), - ('popen', 'HAVE_POPEN', None), - ('pclose', 'HAVE_PCLOSE', None), - ('_open', 'HAVE__OPEN', None), - ('_close', 'HAVE__CLOSE', None), - ('_popen', 'HAVE__POPEN', None), - ('_pclose', 'HAVE__PCLOSE', None), - ('getpid', 'HAVE_GETPID', None), - ('_getpid', 'HAVE__GETPID', None), - ('mkdir', 'HAVE_MKDIR', None), - ('_mkdir', 'HAVE__MKDIR', None), - ('mktemp', 'HAVE_MKTEMP', None), - ('mkstemp', 'HAVE_MKSTEMP', None), - ('strerror', 'HAVE_STRERROR', None), - ('count', 'HAVE_STD_COUNT', ''' -#include -int count() -{ -char a[] = "hello"; -return std::count(a, a+5, 'l'); -} -'''), - ('getcwd', 'HAVE_GETCWD', None), - ('setenv', 'HAVE_SETENV', None), - ('putenv', 'HAVE_PUTENV', None), - ('fcntl', 'HAVE_FCNTL', None), - ], - types = [ - ('std::istreambuf_iterator', 'HAVE_DECL_ISTREAMBUF_ITERATOR', - '#include \n#include ') - ], - libs = [ - ('gdi32', 'HAVE_LIBGDI32'), - (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'), - ], - custom_tests = [ - (conf.CheckType('pid_t', includes='#include '), - 'HAVE_PID_T', - 'Define is sys/types.h does not have pid_t', - '', - '#define pid_t int', - ), - (conf.CheckCXXGlobalCstd(), - 'CXX_GLOBAL_CSTD', - 'Define if your C++ compiler puts C library functions in the global namespace' - ), - (conf.CheckMkdirOneArg(), - 'MKDIR_TAKES_ONE_ARG', - 'Define if mkdir takes only one argument.' - ), - (conf.CheckLC_MESSAGES(), - 'HAVE_LC_MESSAGES', - 'Define if your file defines LC_MESSAGES.' - ), - (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'), - (env['HAVE_ICONV'], - 'HAVE_ICONV', - 'Define to 1 if function iconv exists' - ), - (env['nls'], - 'ENABLE_NLS', - "Define to 1 if translation of program messages to the user's native anguage is requested.", - ), - (env['nls'] and not included_gettext, - 'HAVE_GETTEXT', - 'Define to 1 if using system gettext library' - ), - (env.has_key('warnings') and env['warnings'], - 'WITH_WARNINGS', - 'Define this if you want to see the warning directives put here and there by the developpers to get attention' - ), - (env.has_key('concept_checks') and env['concept_checks'], - '_GLIBCXX_CONCEPT_CHECKS', - 'libstdc++ concept checking' - ), - (env.has_key('stdlib_debug') and env['stdlib_debug'], - '_GLIBCXX_DEBUG', - 'libstdc++ debug mode' - ), - (env.has_key('stdlib_debug') and env['stdlib_debug'], - '_GLIBCXX_DEBUG_PEDANTIC', - 'libstdc++ pedantic debug mode' - ), - (os.name != 'nt', 'BOOST_POSIX', - 'Indicates to boost which API to use (posix or windows).' - ), - (spell_engine is not None, spell_engine, - 'Spell engine to use' - ), - ], - extra_items = [ - ('#define PACKAGE "%s%s"' % (package, program_suffix), - 'Name of package'), - ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport, - 'Define to the address where bug reports for this package should be sent.'), - ('#define PACKAGE_NAME "%s"' % package_name, - 'Define to the full name of this package.'), - ('#define PACKAGE_STRING "%s"' % package_string, - 'Define to the full name and version of this package.'), - ('#define PACKAGE_TARNAME "%s"' % package_tarname, - 'Define to the one symbol short name of this package.'), - ('#define PACKAGE_VERSION "%s"' % package_version, - 'Define to the version of this package.'), - ('#define BOOST_ALL_NO_LIB 1', - 'disable automatic linking of boost libraries.'), - ('#define USE_%s_PACKAGING 1' % packaging_method.upper(), - 'Packaging method'), - ('#define AIKSAURUS_H_LOCATION ' + aik_location, - 'Aiksaurus include file'), - ('#define SELECT_TYPE_ARG1 %s' % select_arg1, - "Define to the type of arg 1 for `select'."), - ('#define SELECT_TYPE_ARG234 %s' % select_arg234, - "Define to the type of arg 2, 3, 4 for `select'."), - ('#define SELECT_TYPE_ARG5 %s' % select_arg5, - "Define to the type of arg 5 for `select'."), - ], - config_post = '''/************************************************************ -** 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 - -#include <../boost/config.h> - -#endif -''' -) - -# these keys are needed in env -for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\ - 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', - 'ICONV_LIB', 'AIKSAURUS_LIB']: - # USE_ASPELL etc does not go through result - if result.has_key(key): - env[key] = result[key] - -# -# if nls=yes and gettext=included, create intl/config.h -# intl/libintl.h etc -# -intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h') -if env['nls'] and included_gettext: - # - print "Creating %s..." % intl_config_h - # - # create intl/config.h - result = utils.createConfigFile(conf, - config_file = intl_config_h, - config_pre = '''/* intl/config.h. Generated by SCons. */ - -/* -*- 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 -''', - headers = [ - ('unistd.h', 'HAVE_UNISTD_H', 'c'), - ('inttypes.h', 'HAVE_INTTYPES_H', 'c'), - ('string.h', 'HAVE_STRING_H', 'c'), - ('strings.h', 'HAVE_STRINGS_H', 'c'), - ('argz.h', 'HAVE_ARGZ_H', 'c'), - ('limits.h', 'HAVE_LIMITS_H', 'c'), - ('alloca.h', 'HAVE_ALLOCA_H', 'c'), - ('stddef.h', 'HAVE_STDDEF_H', 'c'), - ('stdint.h', 'HAVE_STDINT_H', 'c'), - ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'), - ], - functions = [ - ('getcwd', 'HAVE_GETCWD', None), - ('stpcpy', 'HAVE_STPCPY', None), - ('strcasecmp', 'HAVE_STRCASECMP', None), - ('strdup', 'HAVE_STRDUP', None), - ('strtoul', 'HAVE_STRTOUL', None), - ('alloca', 'HAVE_ALLOCA', None), - ('__fsetlocking', 'HAVE___FSETLOCKING', None), - ('mempcpy', 'HAVE_MEMPCPY', None), - ('__argz_count', 'HAVE___ARGZ_COUNT', None), - ('__argz_next', 'HAVE___ARGZ_NEXT', None), - ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None), - ('setlocale', 'HAVE_SETLOCALE', None), - ('tsearch', 'HAVE_TSEARCH', None), - ('getegid', 'HAVE_GETEGID', None), - ('getgid', 'HAVE_GETGID', None), - ('getuid', 'HAVE_GETUID', None), - ('wcslen', 'HAVE_WCSLEN', None), - ('asprintf', 'HAVE_ASPRINTF', None), - ('wprintf', 'HAVE_WPRINTF', None), - ('snprintf', 'HAVE_SNPRINTF', None), - ('printf', 'HAVE_POSIX_PRINTF', None), - ('fcntl', 'HAVE_FCNTL', None), - ], - types = [ - ('intmax_t', 'HAVE_INTMAX_T', None), - ('long double', 'HAVE_LONG_DOUBLE', None), - ('long long', 'HAVE_LONG_LONG', None), - ('wchar_t', 'HAVE_WCHAR_T', None), - ('wint_t', 'HAVE_WINT_T', None), - ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include '), - ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include '), - ], - libs = [ - ('c', 'HAVE_LIBC'), - ], - custom_tests = [ - (conf.CheckLC_MESSAGES(), - 'HAVE_LC_MESSAGES', - 'Define if your file defines LC_MESSAGES.' - ), - (conf.CheckIconvConst(), - 'ICONV_CONST', - 'Define as const if the declaration of iconv() needs const.', - '#define ICONV_CONST const', - '#define ICONV_CONST', - ), - (conf.CheckType('intmax_t', includes='#include ') or \ - conf.CheckType('intmax_t', includes='#include '), - 'HAVE_INTMAX_T', - "Define to 1 if you have the `intmax_t' type." - ), - (env.has_key('nls') and env['nls'], - 'ENABLE_NLS', - "Define to 1 if translation of program messages to the user's native anguage is requested.", - ), - (env['HAVE_ICONV'], - 'HAVE_ICONV', - 'Define to 1 if function iconv exists', - ), - ], - config_post = '#endif' - ) - - # these keys are needed in env - for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \ - 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']: - # USE_ASPELL etc does not go through result - if result.has_key(key): - env[key] = result[key] - -# this looks misplaced, but intl/libintl.h is needed by src/message.C -if env['nls'] and included_gettext: - # libgnuintl.h.in => libintl.h - env.Depends('$TOP_SRCDIR/intl/libintl.h', '$BUILDDIR/intl/config.h') - env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in') - env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h', - [Copy('$TARGET', '$SOURCE')]) - -# -# Finish auto-configuration -env = conf.Finish() - -#---------------------------------------------------------- -# Now set up our build process accordingly -#---------------------------------------------------------- - -# -# QT_LIB -# -# NOTE: Tool('qt') or Tool('qt4') will be loaded later -# in their respective directory and specialized env. -if frontend == 'qt2': - # note: env.Tool('qt') my set QT_LIB to qt - if platform_name == 'win32': - qt_libs = ['qt-mt3'] - else: - qt_libs = ['qt-mt'] - frontend_libs = qt_libs - - -if platform_name in ['win32', 'cygwin']: - # the final link step needs stdc++ to succeed under mingw - # FIXME: shouldn't g++ automatically link to stdc++? - if use_vc: - system_libs = ['ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll'] - else: - system_libs = ['shlwapi', 'stdc++', 'z'] -elif platform_name == 'cygwin' and env['X11']: - system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor', - 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv', - 'pthread', 'z'] -else: - system_libs = ['z'] - -libs = [ - ('HAVE_ICONV', env['ICONV_LIB']), - ('HAVE_LIBGDI32', 'gdi32'), - ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']), - ('USE_ASPELL', aspell_lib), - ('USE_ISPELL', 'ispell'), - ('USE_PSPELL', 'pspell'), -] - -for lib in libs: - if env[lib[0]] and lib[1] is not None: - system_libs.append(lib[1]) - -# -# Build parameters CPPPATH etc -# -if env['X11']: - env.AppendUnique(LIBPATH = ['/usr/X11R6/lib']) - -# -# boost: for boost header files -# BUILDDIR/common: for config.h -# TOP_SRCDIR/src: for support/* etc -# -env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src'] -# -# Separating boost directories from CPPPATH stops scons from building -# the dependency tree for boost header files, and effectively reduce -# the null build time of lyx from 29s to 16s. Since lyx may tweak local -# boost headers, this is only done for system boost headers. -if included_boost: - env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH']) -else: - if use_vc: - env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH']) - else: - env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH']) - -# for intl/config.h, intl/libintl.h and intl/libgnuintl.h -if env['nls'] and included_gettext: - env['CPPPATH'].append('$BUILDDIR/intl') -# -# QT_INC_PATH is not needed for *every* source file -env['CPPPATH'].remove(qt_inc_path) - -# -# A Link script for cygwin see -# http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html -# http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html -# for details -# -if platform_name == 'cygwin': - ld_script_path = '/tmp' - ld_script = utils.installCygwinLDScript(ld_script_path) - env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc', - '-Wl,--script,%s' % ld_script, '-Wl,-s']) - -# -# Report results -# -# fill in the version info -env['VERSION_INFO'] = '''Configuration - Host type: %s - Special build flags: %s - C Compiler: %s - C Compiler flags: %s %s - C++ Compiler: %s - C++ Compiler LyX flags: %s - C++ Compiler flags: %s %s - Linker flags: %s - Linker user flags: %s -Build info: - Builing directory: %s - Local library directory: %s - Libraries paths: %s - Boost libraries: %s - Frontend libraries: %s - System libraries: %s - include search path: %s -Frontend: - Frontend: %s - Packaging: %s - LyX dir: %s - LyX files dir: %s -''' % (platform_name, - env.subst('$CCFLAGS'), env.subst('$CC'), - env.subst('$CPPFLAGS'), env.subst('$CFLAGS'), - env.subst('$CXX'), env.subst('$CXXFLAGS'), - env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'), - env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'), - env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'), - str(env['LIBPATH']), str(boost_libraries), - str(frontend_libs), str(system_libs), str(env['CPPPATH']), - frontend, packaging_method, - prefix, env['LYX_DIR']) - -if frontend == 'qt2': - env['VERSION_INFO'] += ''' include dir: %s - library dir: %s - X11: %s -''' % (qt_inc_path, qt_lib_path, env['X11']) - -print env['VERSION_INFO'] - -# -# Mingw command line may be too short for our link usage, -# Here we use a trick from scons wiki -# http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32 -# -# I also would like to add logging (commands only) capacity to the -# spawn system. -logfile = env.get('logfile', default_log_file) -if logfile != '' or platform_name == 'win32': - import time - utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'), - info = '''# This is a log of commands used by scons to build lyx -# Time: %s -# Command: %s -# Info: %s -''' % (time.asctime(), ' '.join(sys.argv), - env['VERSION_INFO'].replace('\n','\n# ')) ) - - -# Cleanup stuff -# -# -h will print out help info -Help(opts.GenerateHelpText(env)) - - -#---------------------------------------------------------- -# Start building -#---------------------------------------------------------- -# this has been the source of problems on some platforms... -# I find that I need to supply it with full path name -env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign')) -# this usage needs further investigation. -#env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend)) - -print "Building all targets recursively" - -if env.has_key('rebuild'): - rebuild_targets = env['rebuild'].split(',') - if 'none' in rebuild_targets or 'no' in rebuild_targets: - rebuild_targets = [] - elif 'all' in rebuild_targets or 'yes' in rebuild_targets: - # None: let scons decide which components to build - # Forcing all components to be rebuilt is in theory not necessary - rebuild_targets = None -else: - rebuild_targets = None - -def libExists(libname): - ''' Check whether or not lib $LOCALLIBNAME/libname already exists''' - return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath) - -def appExists(apppath, appname): - ''' Check whether or not application already exists''' - return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath) - -targets = BUILD_TARGETS -# msvc need to pass full target name, so I have to look for path/lyx etc -build_lyx = targets == [] or True in ['lyx' in x for x in targets] \ - or 'install' in targets or 'all' in targets -build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets -build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets -build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']] -build_mathed = build_lyx or 'mathed' in targets -build_insets = build_lyx or 'insets' in targets -build_frontends = build_lyx or 'frontends' in targets -build_graphics = build_lyx or 'graphics' in targets -build_controllers = build_lyx or 'controllers' in targets -build_client = True in ['client' in x for x in targets] \ - or 'install' in targets or 'all' in targets -build_tex2lyx = True in ['tex2lyx' in x for x in targets] \ - or 'install' in targets or 'all' in targets -build_lyxbase = build_lyx or 'lyxbase' in targets -build_po = 'po' in targets or 'install' in targets or 'all' in targets -build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets -build_msvs_projects = use_vc and 'msvs_projects' in targets - - -# now, if rebuild_targets is specified, do not rebuild some targets -if rebuild_targets is not None: - # - def ifBuildLib(name, libname, old_value): - # explicitly asked to rebuild - if name in rebuild_targets: - return True - # else if not rebuild, and if the library already exists - elif libExists(libname): - return False - # do not change the original value - else: - return old_value - build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost) - build_intl = ifBuildLib('intl', 'included_intl', build_intl) - build_support = ifBuildLib('support', 'support', build_support) - build_mathed = ifBuildLib('mathed', 'mathed', build_mathed) - build_insets = ifBuildLib('insets', 'insets', build_insets) - build_frontends = ifBuildLib('frontends', 'frontends', build_frontends) - build_graphics = ifBuildLib('graphics', 'graphics', build_graphics) - build_controllers = ifBuildLib('controllers', 'controllers', build_controllers) - build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase) - build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2) - # - def ifBuildApp(name, appname, old_value): - # explicitly asked to rebuild - if name in rebuild_targets: - return True - # else if not rebuild, and if the library already exists - elif appExists(name, appname): - return False - # do not change the original value - else: - return old_value - build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx) - build_client = ifBuildApp('client', 'lyxclient', build_client) - -# sync frontend and frontend -if build_qt2: - frontend = 'qt2' - -if build_boost: - # - # boost libraries - # - # special builddir - env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0) - - boostenv = env.Copy() - # - # boost use its own config.h - boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths - boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG=""']) - - for lib in boost_libs: - print 'Processing files in boost/libs/%s/src...' % lib - boostlib = boostenv.StaticLibrary( - target = '$LOCALLIBPATH/included_boost_%s' % lib, - source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)] - ) - Alias('boost', boostlib) - - -if build_intl: - # - # intl - # - intlenv = env.Copy() - - print "Processing files in intl..." - - env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0) - - # we need the original C compiler for these files - intlenv['CC'] = C_COMPILER - intlenv['CCFLAGS'] = C_CCFLAGS - if use_vc: - intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX']) - # intl does not use global config.h - intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths - - intlenv.Append(CCFLAGS = [ - r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"', - r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"', - r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"', - '-DIN_LIBINTL', - '-DENABLE_RELOCATABLE=1', - '-DIN_LIBRARY', - r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"', - '-DNO_XMALLOC', - '-Dset_relocation_prefix=libintl_set_relocation_prefix', - '-Drelocate=libintl_relocate', - '-DDEPENDS_ON_LIBICONV=1', - '-DHAVE_CONFIG_H' - ] - ) - - intl = intlenv.StaticLibrary( - target = '$LOCALLIBPATH/included_intl', - LIBS = ['c'], - source = ['$BUILDDIR/intl/%s' % x for x in intl_files] - ) - Alias('intl', intl) - - -# -# Now, src code under src/ -# -env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0) - - -if build_support: - # - # src/support - # - print "Processing files in src/support..." - - env.Depends('$BUILDDIR/common/support/package.C', '$BUILDDIR/common/config.h') - env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in') - - support = env.StaticLibrary( - target = '$LOCALLIBPATH/support', - source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files] - ) - Alias('support', support) - - -if build_mathed: - # - # src/mathed - # - print "Processing files in src/mathed..." - # - mathed = env.StaticLibrary( - target = '$LOCALLIBPATH/mathed', - source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files] - ) - Alias('mathed', mathed) - - -if build_insets: - # - # src/insets - # - print "Processing files in src/insets..." - # - insets = env.StaticLibrary( - target = '$LOCALLIBPATH/insets', - source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files] - ) - Alias('insets', insets) - - -if build_frontends: - # - # src/frontends - # - print "Processing files in src/frontends..." - - frontends = env.StaticLibrary( - target = '$LOCALLIBPATH/frontends', - source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files] - ) - Alias('frontends', frontends) - - -if build_graphics: - # - # src/graphics - # - print "Processing files in src/graphics..." - - graphics = env.StaticLibrary( - target = '$LOCALLIBPATH/graphics', - source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files] - ) - Alias('graphics', graphics) - - -if build_controllers: - # - # src/frontends/controllers - # - print "Processing files in src/frontends/controllers..." - - controllers = env.StaticLibrary( - target = '$LOCALLIBPATH/controllers', - source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files] - ) - Alias('controllers', controllers) - - -# -# src/frontend/qt3/4 -# -if build_qt2: - env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0) - - print "Processing files in src/frontends/qt2..." - - qt2env = env.Copy() - # disable auto scan to speed up non build time - qt2env['QT_AUTOSCAN'] = 0 - qt2env['QT_MOCHPREFIX'] = '' - - # load qt2 tools - qt2env.Tool('qt') - qt2env['QT_UICDECLFLAGS'] = '-tr qt_' - qt2env['QT_UICIMPLFLAGS'] = '-tr qt_' - - qt2env.AppendUnique(CPPPATH = [ - '$BUILDDIR/common', - '$BUILDDIR/common/images', - '$BUILDDIR/common/frontends', - '$BUILDDIR/common/frontends/qt2', - '$BUILDDIR/common/frontends/controllers', - qt_inc_path] - ) - - qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in src_frontends_qt2_moc_files] - - # manually moc and uic files for better performance - qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files] - - qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \ - src_frontends_qt2_ui_files] - - qt2_uiced_cc_files = [] - for x in qt2_uiced_files: - qt2_uiced_cc_files.extend(x[1:]) - - qt2 = qt2env.StaticLibrary( - target = '$LOCALLIBPATH/qt2', - source = ['$BUILDDIR/common/frontends/qt2/%s' % x for x in src_frontends_qt2_files] \ - + qt2_moced_files + qt2_uiced_cc_files - ) - Alias('qt2', qt2) - - -if build_client: - # - # src/client - # - env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0) - - print "Processing files in src/client..." - - if env['HAVE_FCNTL']: - client = env.Program( - target = '$BUILDDIR/common/client/lyxclient', - LIBS = ['support'] + intl_libs + system_libs + - socket_libs + boost_libraries, - source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files] + \ - utils.createResFromIcon(env, 'lyx_32x32.ico', '$LOCALLIBPATH/client.rc') - - ) - Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]), - client, [Copy('$TARGET', '$SOURCE')])) - else: - client = None - Alias('client', client) -else: - if env['HAVE_FCNTL']: - # define client even if lyxclient is not built with rebuild=no - client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')] - else: - client = None - - -if build_tex2lyx: - # - # tex2lyx - # - print "Processing files in src/tex2lyx..." - - tex2lyx_env = env.Copy() - # - tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx']) - tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH']) - - for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C', - 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']: - env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file, - [Copy('$TARGET', '$SOURCE')]) - - tex2lyx = tex2lyx_env.Program( - target = '$BUILDDIR/common/tex2lyx/tex2lyx', - LIBS = ['support'] + boost_libraries + system_libs, - source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files] + \ - utils.createResFromIcon(tex2lyx_env, 'lyx_32x32.ico', '$LOCALLIBPATH/tex2lyx.rc') - ) - Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]), - tex2lyx, [Copy('$TARGET', '$SOURCE')])) - Alias('tex2lyx', tex2lyx) -else: - # define tex2lyx even if tex2lyx is not built with rebuild=no - tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')] - - -if build_lyxbase: - # - # src/ - # - print "Processing files in src..." - - env.Depends('$BUILDDIR/common/version.C', '$BUILDDIR/common/config.h') - env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in') - - if env.has_key('USE_ASPELL') and env['USE_ASPELL']: - src_post_files.append('aspell.C') - elif env.has_key('USE_PSPELL') and env['USE_PSPELL']: - src_post_files.append('pspell.C') - elif env.has_key('USE_ISPELL') and env['USE_ISPELL']: - src_post_files.append('ispell.C') - - # msvc requires at least one source file with main() - # so I exclude main.C from lyxbase - lyxbase_pre = env.StaticLibrary( - target = '$LOCALLIBPATH/lyxbase_pre', - source = ['$BUILDDIR/common/%s' % x for x in src_pre_files] - ) - lyxbase_post = env.StaticLibrary( - target = '$LOCALLIBPATH/lyxbase_post', - source = ["$BUILDDIR/common/%s" % x for x in src_post_files] - ) - Alias('lyxbase', lyxbase_pre) - Alias('lyxbase', lyxbase_post) - - -if build_lyx: - # - # Build lyx with given frontend - # - lyx = env.Program( - target = '$BUILDDIR/lyx', - source = ['$BUILDDIR/common/main.C'] + \ - utils.createResFromIcon(env, 'lyx_32x32.ico', '$LOCALLIBPATH/lyx.rc'), - LIBS = [ - 'lyxbase_pre', - 'mathed', - 'insets', - 'frontends', - frontend, - 'controllers', - 'graphics', - 'support', - 'lyxbase_post', - ] + - boost_libraries + - frontend_libs + - intl_libs + - socket_libs + - system_libs - ) - Alias('lyx', lyx) -else: - # define lyx even if lyx is not built with rebuild=no - lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')] - - -if build_msvs_projects: - def build_project(target, full_target = None, - src = [], inc = [], res = [], rebuildTargetOnly = True): - ''' build mavs project files - target: alias (correspond to directory name) - full_target: full path/filename of the target - src: source files - inc: include files - res: resource files - rebuildTargetOnly: whether or not only rebuild this target - - For non-debug-able targets like static libraries, target (alias) is - enough to build the target. For executable targets, msvs need to know - the full path to start debug them. - ''' - if rebuildTargetOnly: - cmds = 'rebuild='+target - else: - cmds = '' - if full_target is None: - build_target = target - else: - build_target = full_target - # project - proj = env.MSVSProject( - target = target + env['MSVSPROJECTSUFFIX'], - # this allows easy access to header files (along with source) - srcs = [env.subst(x) for x in src + inc], - incs = [env.subst('$TOP_SRCDIR/src/config.h')], - localincs = [env.subst(x) for x in inc], - resources = [env.subst(x) for x in res], - buildtarget = build_target, - cmdargs = cmds, - variant = 'Debug' - ) - Alias('msvs_projects', proj) - # - boost_src = [] - for lib in boost_libs: - boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)] - build_project('boost', src = boost_src) - # - build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files], - inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files]) - # - build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], - inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files]) - # - build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], - inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files]) - # - build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files], - inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files]) - # - build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files], - inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files]) - # - build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files], - inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files]) - # - build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files], - inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files]) - # - build_project('qt2', src = ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_files + src_frontends_qt2_moc_files], - inc = ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_header_files], - res = ['$TOP_SRCDIR/src/frontends/qt2/ui/%s' % x for x in src_frontends_qt2_ui_files]) - # - build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files], - inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files], - rebuildTargetOnly = False, - full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath) - # - build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files], - inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files], - rebuildTargetOnly = False, - full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath) - # - build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files], - inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files]) - # - if frontend == 'qt2': - build_project('lyx', - src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \ - ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \ - ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \ - ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \ - ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \ - ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \ - ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \ - ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_files + src_frontends_qt2_moc_files], - inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \ - ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \ - ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \ - ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \ - ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \ - ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \ - ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \ - ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_header_files], - res = ['$TOP_SRCDIR/src/frontends/qt2/ui/%s' % x for x in src_frontends_qt2_ui_files], - rebuildTargetOnly = False, - full_target = File(env.subst('$BUILDDIR/lyx$PROGSUFFIX')).abspath) - - -if build_po: - # - # po/ - # - print 'Processing files in po...' - - import glob - # handle po files - # - # files to translate - transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po')) - # possibly *only* handle these languages - languages = None - if env.has_key('languages'): - languages = env.make_list(env['lanauges']) - # use defulat msgfmt - gmo_files = [] - if not env['MSGFMT']: - print 'msgfmt does not exist. Can not process po files' - else: - # create a builder - env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po') - # - for f in transfiles: - # get filename - fname = os.path.split(f)[1] - # country code - country = fname.split('.')[0] - # - if not languages or country in languages: - gmo_files.extend(env.Transfiles(f)) - - -if 'install' in targets: - # - # this part is a bit messy right now. Since scons will provide - # --DESTDIR option soon, at least the dest_dir handling can be - # removed later. - # - # how to join dest_dir and prefix - def joinPaths(path1, path2): - ''' join path1 and path2, do not use os.path.join because - under window, c:\destdir\d:\program is invalid ''' - if path1 == '': - return os.path.normpath(path2) - # separate drive letter - (drive, path) = os.path.splitdrive(os.path.normpath(path2)) - # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program - return os.path.join(os.path.normpath(path1), path[1:]) - # - # install to dest_dir/prefix - dest_dir = env.get('DESTDIR', '') - dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath) - # create the directory if needed - if not os.path.isdir(dest_prefix_dir): - try: - os.makedirs(dest_prefix_dir) - except: - pass - if not os.path.isdir(dest_prefix_dir): - print 'Can not create directory', dest_prefix_dir - Exit(3) - # - if env.has_key('exec_prefix'): - bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath) - else: - bin_dest_dir = os.path.join(dest_prefix_dir, 'bin') - if add_suffix: - share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix) - else: - share_dest_dir = os.path.join(dest_prefix_dir, share_dir) - man_dest_dir = os.path.join(dest_prefix_dir, man_dir) - locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir) - # - import glob - # - # install executables (lyxclient may be None) - # - if add_suffix: - version_suffix = program_suffix - else: - version_suffix = '' - # - # install lyx, if in release mode, try to strip the binary - if env.has_key('STRIP') and env['STRIP'] is not None and mode != 'debug': - # create a builder to strip and install - env['BUILDERS']['StripInstallAs'] = Builder(action='$STRIP $SOURCE -o $TARGET') - - # install executables - for (name, obj) in (('lyx', lyx), ('tex2lyx', tex2lyx), ('client', client)): - if obj is None: - continue - target_name = os.path.split(str(obj[0]))[1].replace(name, '%s%s' % (name, version_suffix)) - target = os.path.join(bin_dest_dir, target_name) - if env['BUILDERS'].has_key('StripInstallAs'): - env.StripInstallAs(target, obj) - else: - env.InstallAs(target, obj) - Alias('install', target) - # - # share/lyx - dirs = [] - for (dir,files) in [ - ('.', lib_files), - ('clipart', lib_clipart_files), - ('examples', lib_examples_files), - ('images', lib_images_files), - ('images/math', lib_images_math_files), - ('bind', lib_bind_files), - ('kbd', lib_kbd_files), - ('layouts', lib_layouts_files), - ('scripts', lib_scripts_files), - ('templates', lib_templates_files), - ('tex', lib_tex_files), - ('ui', lib_ui_files), - ('doc', lib_doc_files), - ('lyx2lyx', lib_lyx2lyx_files)]: - dirs.append(env.Install(os.path.join(share_dest_dir, dir), - [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files])) - Alias('install', dirs) - - if platform_name == 'cygwin': - # cygwin packaging requires a file /usr/share/doc/Cygwin/foot-vendor-suffix.README - Cygwin_README = os.path.join(dest_prefix_dir, 'share', 'doc', 'Cygwin', - '%s-%s.README' % (package, package_cygwin_version)) - env.InstallAs(Cygwin_README, - os.path.join(env.subst('$TOP_SRCDIR'), 'README.cygwin')) - Alias('install', Cygwin_README) - # also a directory /usr/share/doc/lyx for README etc - Cygwin_Doc = os.path.join(dest_prefix_dir, 'share', 'doc', package) - env.Install(Cygwin_Doc, [os.path.join(env.subst('$TOP_SRCDIR'), x) for x in \ - ['INSTALL', 'README', 'README.Cygwin', 'RELEASE-NOTES', 'COPYING', 'ANNOUNCE']]) - Alias('install', Cygwin_Doc) - # cygwin fonts also need to be installed - Cygwin_fonts = os.path.join(share_dest_dir, 'fonts') - env.Install(Cygwin_fonts, - [env.subst('$TOP_SRCDIR/development/Win32/packaging/bakoma/%s' % file) \ - for file in win32_bakoma_fonts]) - Alias('install', Cygwin_fonts) - # we also need a post installation script - tmp_script = utils.installCygwinPostinstallScript('/tmp') - postinstall_path = os.path.join(dest_dir, 'etc', 'postinstall') - env.Install(postinstall_path, tmp_script) - Alias('install', postinstall_path) - - # man - env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'), - env.subst('$TOP_SRCDIR/lyx.man')) - env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'), - env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man')) - env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'), - env.subst('$TOP_SRCDIR/src/client/lyxclient.man')) - Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for - x in ['lyx', 'tex2lyx', 'lyxclient']]) - # locale files? - # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo - for gmo in gmo_files: - lan = os.path.split(str(gmo))[1].split('.')[0] - dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo') - env.InstallAs(dest_file, gmo) - Alias('install', dest_file) - - -Default('lyx') -Alias('all', ['lyx', 'client', 'tex2lyx']) +# vi:filetype=python:expandtab:tabstop=4:shiftwidth=4 +# +# file SConstruct +# +# 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 is a scons based building system for lyx, please refer +# to INSTALL.scons for detailed instructions. +# + +import os, sys, copy, cPickle, glob, time + +# scons_utils.py defines a few utility function +sys.path.append('config') +import scons_utils as utils +# import all file lists +from scons_manifest import * + +#---------------------------------------------------------- +# Required runtime environment +#---------------------------------------------------------- + +# scons asks for 1.5.2, lyx requires 2.3 +EnsurePythonVersion(2, 3) +# Please use at least 0.96.92 (not 0.96.1) +EnsureSConsVersion(0, 96) +# also check for minor version number for scons 0.96 +from SCons import __version__ +version = map(int, __version__.split('.')) +if version[0] == 0 and version[1] == 96 and version[2] < 92: + print "Scons >= 0.96.92 is required." + Exit(1) + +# determine where I am ... +# +from SCons.Node.FS import default_fs +# default_fs.SConstruct_dir is where SConstruct file is located. +scons_dir = default_fs.SConstruct_dir.path +# get the ../.. of scons_dir +top_src_dir = os.path.split(os.path.split(default_fs.SConstruct_dir.abspath)[0])[0] + + +#---------------------------------------------------------- +# Global definitions +#---------------------------------------------------------- + +# some global settings +# +# get version number from configure.ac so that JMarc does +# not have to change SConstruct during lyx release +package_version = utils.getVerFromConfigure(top_src_dir) +package_cygwin_version = '%s-1' % package_version +boost_version = ['1_32'] + +if 'svn' in package_version: + devel_version = True + default_build_mode = 'debug' +else: + devel_version = False + default_build_mode = 'release' + +package = 'lyx' +package_bugreport = 'lyx-devel@lists.lyx.org' +package_name = 'LyX' +package_tarname = 'lyx' +package_string = '%s %s' % (package_name, package_version) + +# various cache/log files +default_log_file = 'scons_lyx.log' +opt_cache_file = 'opt.cache' + + +#---------------------------------------------------------- +# platform dependent settings +#---------------------------------------------------------- + +if os.name == 'nt': + platform_name = 'win32' + default_prefix = 'c:/program files/lyx' + default_with_x = False + default_packaging_method = 'windows' +elif os.name == 'posix' and sys.platform != 'cygwin': + platform_name = sys.platform + default_prefix = '/usr/local' + default_with_x = True + default_packaging_method = 'posix' +elif os.name == 'posix' and sys.platform == 'cygwin': + platform_name = 'cygwin' + default_prefix = '/usr' + default_with_x = True + default_packaging_method = 'posix' +elif os.name == 'darwin': + platform_name = 'macosx' + # FIXME: macOSX default prefix? + default_prefix = '.' + default_with_x = False + default_packaging_method = 'macosx' +else: # unsupported system, assume posix behavior + platform_name = 'others' + default_prefix = '.' + default_with_x = True + default_packaging_method = 'posix' + +#--------------------------------------------------------- +# Handling options +#---------------------------------------------------------- +# +# You can set perminant default values in config.py +if os.path.isfile('config.py'): + print "Getting options from config.py..." + print open('config.py').read() + +opts = Options(['config.py']) +opts.AddOptions( + # frontend + EnumOption('frontend', 'Main GUI', 'qt2', + allowed_values = ('qt2',) ), + # debug or release build + EnumOption('mode', 'Building method', default_build_mode, + allowed_values = ('debug', 'release') ), + # boost libraries + EnumOption('boost', + 'Use included, system boost library, or try sytem boost first.', + 'auto', allowed_values = ( + 'auto', # detect boost, if not found, use included + 'included', # always use included boost + 'system', # always use system boost, fail if can not find + ) ), + # + EnumOption('gettext', + 'Use included, system gettext library, or try sytem gettext first', + 'auto', allowed_values = ( + 'auto', # detect gettext, if not found, use included + 'included', # always use included gettext + 'system', # always use system gettext, fail if can not find + ) ), + # + EnumOption('spell', 'Choose spell checker to use.', 'auto', + allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ), + # packaging method + EnumOption('packaging', 'Packaging method to use.', default_packaging_method, + allowed_values = ('windows', 'posix', 'macosx')), + # + BoolOption('fast_start', 'This option is obsolete.', False), + # No precompiled header support (too troublesome to make it work for msvc) + # BoolOption('pch', 'Whether or not use pch', False), + # enable assertion, (config.h has ENABLE_ASSERTIOS + BoolOption('assertions', 'Use assertions', True), + # enable warning, (config.h has WITH_WARNINGS) + # default to False since MSVC does not have #warning + BoolOption('warnings', 'Use warnings', False), + # config.h define _GLIBCXX_CONCEPT_CHECKS + # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS + BoolOption('concept_checks', 'Enable concept checks', True), + # + BoolOption('nls', 'Whether or not use native language support', True), + # + BoolOption('profiling', 'Whether or not enable profiling', False), + # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC + BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False), + # using x11? + BoolOption('X11', 'Use x11 windows system', default_with_x), + # use MS VC++ to build lyx + BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None), + # + PathOption('qt_dir', 'Path to qt directory', None), + # + PathOption('qt_inc_path', 'Path to qt include directory', None), + # + PathOption('qt_lib_path', 'Path to qt library directory', None), + # extra include and libpath + PathOption('extra_inc_path', 'Extra include path', None), + # + PathOption('extra_lib_path', 'Extra library path', None), + # + PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None), + # + PathOption('extra_inc_path1', 'Extra include path', None), + # + PathOption('extra_lib_path1', 'Extra library path', None), + # rebuild only specifed, comma separated targets + ('rebuild', '''rebuild only specifed, comma separated targets. + yes or all (default): rebuild everything + no or none: rebuild nothing (usually used for installation) + comp1,comp2,...: rebuild specified targets''', None), + # can be set to a non-existing directory + ('prefix', 'install architecture-independent files in PREFIX', default_prefix), + # build directory, will use $mode if not set + ('build_dir', 'Build directory', None), + # version suffix + ('version_suffix', 'install lyx as lyx-suffix', None), + # how to load options + ('load_option', '''load option from previous scons run. option can be + yes (default): load all options + no: do not load any option + opt1,opt2: load specified options + -opt1,opt2: load all options other than specified ones''', 'yes'), + # + ('optimization', 'optimization CCFLAGS option.', None), + # + PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None), + # log file + ('logfile', 'save commands (not outputs) to logfile', default_log_file), + # provided for backward compatibility + ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None), + # environment variable can be set as options. + ('DESTDIR', 'install to DESTDIR', None), + ('CC', 'replace default $CC', None), + ('LINK', 'replace default $LINK', None), + ('CPP', 'replace default $CPP', None), + ('CXX', 'replace default $CXX', None), + ('CXXCPP', 'replace default $CXXCPP', None), + ('CCFLAGS', 'replace default $CCFLAGS', None), + ('CPPFLAGS', 'replace default $CPPFLAGS', None), + ('LINKFLAGS', 'replace default $LINKFLAGS', None), +) + +# allowed options +all_options = [x.key for x in opts.options] + +# copied from SCons/Options/BoolOption.py +# We need to use them before a boolean ARGUMENTS option is available +# in env as bool. +true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' ) +false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none') + +if ARGUMENTS.has_key('fast_start'): + print 'fast_start option is obsolete' + +# if load_option=yes (default), load saved comand line options +# +# This option can take value yes/no/opt1,opt2/-opt1,opt2 +# and tries to be clever in choosing options to load +if (not ARGUMENTS.has_key('load_option') or \ + ARGUMENTS['load_option'] not in false_strings) \ + and os.path.isfile(opt_cache_file): + cache_file = open(opt_cache_file) + opt_cache = cPickle.load(cache_file) + cache_file.close() + # import cached options, but we should ignore qt_dir when frontend changes + if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \ + and ARGUMENTS['frontend'] != opt_cache['frontend'] \ + and opt_cache.has_key('qt_dir'): + opt_cache.pop('qt_dir') + # and we do not cache some options (dest_dir is obsolete) + for arg in ['load_option', 'dest_dir']: + if opt_cache.has_key(arg): + opt_cache.pop(arg) + # remove obsolete cached keys (well, SConstruct is evolving. :-) + for arg in opt_cache.keys(): + if arg not in all_options: + print 'Option %s is obsolete, do not load it' % arg + opt_cache.pop(arg) + # now, if load_option=opt1,opt2 or -opt1,opt2 + if ARGUMENTS.has_key('load_option') and \ + ARGUMENTS['load_option'] not in true_strings + false_strings: + # if -opt1,opt2 is specified, do not load these options + if ARGUMENTS['load_option'][0] == '-': + for arg in ARGUMENTS['load_option'][1:].split(','): + if opt_cache.has_key(arg): + opt_cache.pop(arg) + # if opt1,opt2 is specified, only load specified options + else: + args = ARGUMENTS['load_option'].split(',') + for arg in opt_cache.keys(): + if arg not in args: + opt_cache.pop(arg) + # now restore options as if entered from command line + for key in opt_cache.keys(): + if not ARGUMENTS.has_key(key): + ARGUMENTS[key] = opt_cache[key] + print "Restoring cached option %s=%s" % (key, ARGUMENTS[key]) + print + +# check if there is unused (or misspelled) argument +for arg in ARGUMENTS.keys(): + if arg not in all_options: + import textwrap + print "Unknown option '%s'... exiting." % arg + print + print "Available options are (check 'scons -help' for details):" + print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options))) + Exit(1) + +# save options used +cache_file = open(opt_cache_file, 'w') +cPickle.dump(ARGUMENTS, cache_file) +cache_file.close() + + +#--------------------------------------------------------- +# Setting up environment +#--------------------------------------------------------- + +# I do not really like ENV=os.environ, but you may add it +# here if you experience some environment related problem +env = Environment(options = opts) + +# set individual variables since I do not really like ENV = os.environ +env['ENV']['PATH'] = os.environ.get('PATH') +env['ENV']['HOME'] = os.environ.get('HOME') +# these are defined for MSVC +env['ENV']['LIB'] = os.environ.get('LIB') +env['ENV']['INCLUDE'] = os.environ.get('INCLUDE') + +# for simplicity, use var instead of env[var] +frontend = env['frontend'] +prefix = env['prefix'] +mode = env['mode'] + +if platform_name == 'win32': + if env.has_key('use_vc'): + use_vc = env['use_vc'] + if WhereIs('cl.exe') is None: + print "cl.exe is not found. Are you using the MSVC environment?" + Exit(2) + elif WhereIs('cl.exe') is not None: + use_vc = True + else: + use_vc = False +else: + use_vc = False + +# lyx will be built to $build/build_dir so it is possible +# to build multiple build_dirs using the same source +# $mode can be debug or release +if env.has_key('build_dir') and env['build_dir'] is not None: + # create the directory if needed + if not os.path.isdir(env['build_dir']): + try: + os.makedirs(env['build_dir']) + except: + pass + if not os.path.isdir(env['build_dir']): + print 'Can not create directory', env['build_dir'] + Exit(3) + env['BUILDDIR'] = env['build_dir'] +else: + # Determine the name of the build $mode + env['BUILDDIR'] = '#' + mode + +# all built libraries will go to build_dir/libs +# (This is different from the make file approach) +env['LOCALLIBPATH'] = '$BUILDDIR/libs' +env.AppendUnique(LIBPATH = ['$LOCALLIBPATH']) + + +# Here is a summary of variables defined in env +# 1. defined options +# 2. undefined options with a non-None default value +# 3. compiler commands and flags like CCFLAGS. +# MSGFMT used to process po files +# 4. Variables that will be used to replace variables in some_file.in +# src/support/package.C.in: +# TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX +# lib/lyx2lyx/lyx2lyx_version.py.in +# PACKAGE_VERSION +# src/version.C.in +# PACKAGE_VERSION, LYX_DATE, VERSION_INFO + +# full path name is used to build msvs project files +# and to replace TOP_SRCDIR in package.C +env['TOP_SRCDIR'] = Dir(top_src_dir).abspath +# needed by src/version.C.in => src/version.C +env['PACKAGE_VERSION'] = package_version +env['LYX_DATE'] = time.asctime() + +# determine share_dir etc +packaging_method = env.get('packaging') +if packaging_method == 'windows': + share_dir = 'Resources' + man_dir = 'Resources/man/man1' + locale_dir = 'Resources/locale' +else: + share_dir = 'share/lyx' + locale_dir = 'share/locale' + if platform_name == 'cygwin': + man_dir = 'share/man/man1' + else: + man_dir = 'man/man1' + +# program suffix: can be yes, or a string +if env.has_key('version_suffix'): + if env['version_suffix'] in true_strings: + program_suffix = package_version + elif env['version_suffix'] in false_strings: + program_suffix = '' + else: + program_suffix = env['version_suffix'] +else: + program_suffix = '' +# used by package.C.in +env['PROGRAM_SUFFIX'] = program_suffix + +# whether or not add suffix to file and directory names +add_suffix = packaging_method != 'windows' +# LYX_DIR are different (used in package.C.in) +if add_suffix: + env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath +else: + env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath +# we need absolute path for package.C +env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath + + +#--------------------------------------------------------- +# Setting building environment (Tools, compiler flags etc) +#--------------------------------------------------------- + +# Since Tool('mingw') will reset CCFLAGS etc, this should be +# done before getEnvVariable +if platform_name == 'win32': + if use_vc: + env.Tool('msvc') + env.Tool('mslink') + else: + env.Tool('mingw') + env.AppendUnique(CPPPATH = ['#c:/MinGW/include']) + # fix a scons winres bug (there is a missing space between ${RCINCPREFIX} and ${SOURCE.dir} + # in version 0.96.93 + env['RCCOM'] = '$RC $_CPPDEFFLAGS $RCINCFLAGS ${RCINCPREFIX} ${SOURCE.dir} $RCFLAGS -i $SOURCE -o $TARGET' + + +# we differentiate between hard-coded options and default options +# hard-coded options are required and will always be there +# default options can be replaced by enviromental variables or command line options +CCFLAGS_required = [] +LINKFLAGS_required = [] +CCFLAGS_default = [] + +# under windows, scons is confused by .C/.c and uses gcc instead of +# g++. I am forcing the use of g++ here. This is expected to change +# after lyx renames all .C files to .cpp +# +# save the old c compiler and CCFLAGS (used by libintl) +C_COMPILER = env.subst('$CC') +C_CCFLAGS = env.subst('$CCFLAGS').split() +# if we use ms vc, the commands are fine (cl.exe and link.exe) +if use_vc: + # /TP treat all source code as C++ + # C4819: The file contains a character that cannot be represented + # in the current code page (number) + # C4996: foo was decleared deprecated + CCFLAGS_required.extend(['/TP', '/EHsc']) + if mode == 'debug': + CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MDd']) + # the flags are also needed in C mode (for intl lib) + C_CCFLAGS.extend(['/wd4819', '/wd4996', '/nologo', '/MDd']) + else: + CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MD']) + C_CCFLAGS.extend(['/wd4819', '/wd4996', '/nologo', '/MD']) +else: + if env.has_key('CXX') and env['CXX']: + env['CC'] = env.subst('$CXX') + env['LINK'] = env.subst('$CXX') + else: + env['CC'] = 'g++' + env['LINK'] = 'g++' + +# for debug/release mode +if env.has_key('optimization') and env['optimization'] is not None: + # if user supplies optimization flags, use it anyway + CCFLAGS_required.extend(env['optimization'].split()) + # and do not use default + set_default_optimization_flags = False +else: + set_default_optimization_flags = True + +if mode == 'debug': + if use_vc: + CCFLAGS_required.append('/Zi') + LINKFLAGS_required.extend(['/debug', '/map']) + else: + CCFLAGS_required.append('-g') + CCFLAGS_default.append('-O') +elif mode == 'release' and set_default_optimization_flags: + if use_vc: + CCFLAGS_default.append('/O2') + else: + CCFLAGS_default.append('-O2') + +# msvc uses separate tools for profiling +if env.has_key('profiling') and env['profiling']: + if use_vc: + print 'Visual C++ does not use profiling options' + else: + CCFLAGS_required.append('-pg') + LINKFLAGS_required.append('-pg') + +if env.has_key('warnings') and env['warnings']: + if use_vc: + CCFLAGS_default.append('/W2') + else: + # Note: autotools detect gxx version and pass -W for 3.x + # and -Wextra for other versions of gcc + CCFLAGS_default.append('-Wall') + +# Now, set the variables as follows: +# 1. if command line option exists: replace default +# 2. then if s envronment variable exists: replace default +# 3. set variable to required + default +def setEnvVariable(env, name, required = None, default = None, split = True): + ''' env: environment to set variable + name: variable + required: hardcoded options + default: default options that can be replaced by command line or + environment variables + split: whether or not split obtained variable like '-02 -g' + ''' + # 1. ARGUMENTS is already set to env[name], override default. + if ARGUMENTS.has_key(name): + # env[name] may be rewritten when building tools are reloaded + # if that is the case, commandline option will override it. + env[name] = ARGUMENTS[name] + default = None + # then use environment default + elif os.environ.has_key(name): + print "Acquiring variable %s from system environment: %s" % (name, os.environ[name]) + default = os.environ[name] + if split: + default = default.split() + # the real value should be env[name] + default + required + if split: + value = [] + if env.has_key(name): + value = str(env[name]).split() + if required is not None: + value += required + if default is not None: + value += default + else: + value = "" + if env.has_key(name): + value = str(env[name]) + if required is not None: + value += " " + required + if default is not None: + value += " " + default + env[name] = value + # print name, env[name] + +setEnvVariable(env, 'DESTDIR', split=False) +setEnvVariable(env, 'CC') +setEnvVariable(env, 'LINK') +setEnvVariable(env, 'CPP') +setEnvVariable(env, 'CXX') +setEnvVariable(env, 'CXXCPP') +setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default) +setEnvVariable(env, 'CXXFLAGS') +setEnvVariable(env, 'CPPFLAGS') +setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required) + +# if DESTDIR is not set... +if env.has_key('dest_dir'): + print "This option is obsolete. Please use DESTDIR instead." + env['DESTDIR'] = env['dest_dir'] + + +#--------------------------------------------------------- +# Frontend related variables (QTDIR etc) +#--------------------------------------------------------- + +if env.has_key('qt_dir') and env['qt_dir']: + env['QTDIR'] = env['qt_dir'] +elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')): + env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3') + +# if there is a valid QTDIR, set path for lib and bin directories +if env.has_key('QTDIR'): + # add path to the qt tools + if os.path.isdir(os.path.join(env['QTDIR'], 'lib')): + env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')]) + # set environment so that moc etc can be found even if its path is not set properly + if os.path.isdir(os.path.join(env['QTDIR'], 'bin')): + os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin') + env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin')) + +# frontend name is qt2, but we are looking for qt3 libs +frontend_lib = 'qt3' +if env.has_key('qt_lib_path') and env['qt_lib_path']: + qt_lib_path = env.subst('$qt_lib_path') +elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')): + qt_lib_path = env.subst('$QTDIR/lib') +# this is the path for cygwin. +elif os.path.isdir(os.path.join('/usr/lib/', frontend_lib, 'lib')): + qt_lib_path = '/usr/lib/%s/lib' % frontend_lib +else: + print "Qt library directory is not found. Please specify it using qt_lib_path" + Exit(1) +env.AppendUnique(LIBPATH = [qt_lib_path]) +# qt4 seems to be using pkg_config +env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path) + +if env.has_key('qt_inc_path') and env['qt_inc_path']: + qt_inc_path = env['qt_inc_path'] +elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')): + qt_inc_path = '$QTDIR/include' +# this is the path for cygwin. +elif os.path.isdir('/usr/include/' + frontend_lib): + qt_inc_path = '/usr/include/' + frontend_lib +else: + print "Qt include directory not found. Please specify it using qt_inc_path" + Exit(1) +# Note that this CPPPATH is for testing only +# it will be removed before calling SConscript +env['CPPPATH'] = [qt_inc_path] + +# +# extra_inc_path and extra_lib_path +# +extra_inc_paths = [] +if env.has_key('extra_inc_path') and env['extra_inc_path']: + extra_inc_paths.append(env['extra_inc_path']) +if env.has_key('extra_lib_path') and env['extra_lib_path']: + env.AppendUnique(LIBPATH = [env['extra_lib_path']]) +if env.has_key('extra_inc_path1') and env['extra_inc_path1']: + extra_inc_paths.append(env['extra_inc_path1']) +if env.has_key('extra_lib_path1') and env['extra_lib_path1']: + env.AppendUnique(LIBPATH = [env['extra_lib_path1']]) +if env.has_key('extra_bin_path') and env['extra_bin_path']: + # only the first one is needed (a scons bug?) + os.environ['PATH'] += os.pathsep + env['extra_bin_path'] + env.PrependENVPath('PATH', env['extra_bin_path']) +# extra_inc_paths will be used later by intlenv etc +env.AppendUnique(CPPPATH = extra_inc_paths) + + +#---------------------------------------------------------- +# Autoconf business +#---------------------------------------------------------- + +conf = Configure(env, + custom_tests = { + 'CheckPkgConfig' : utils.checkPkgConfig, + 'CheckPackage' : utils.checkPackage, + 'CheckMkdirOneArg' : utils.checkMkdirOneArg, + 'CheckSelectArgType' : utils.checkSelectArgType, + 'CheckBoostLibraries' : utils.checkBoostLibraries, + 'CheckCommand' : utils.checkCommand, + 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd, + 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES, + 'CheckIconvConst' : utils.checkIconvConst, + } +) + +# pkg-config? (if not, we use hard-coded options) +if conf.CheckPkgConfig('0.15.0'): + env['HAS_PKG_CONFIG'] = True +else: + print 'pkg-config >= 0.1.50 is not found' + env['HAS_PKG_CONFIG'] = False + +# zlib? This is required. +if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \ + or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')): + print 'Did not find zdll.lib or zlib.h, exiting!' + Exit(1) + +# +# qt3 does not use pkg_config +if frontend == 'qt2': + # windows lib name is qt-mt3 + if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \ + and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'): + print 'Did not find qt libraries, exiting!' + Exit(1) + +# now, if msvc2005 is used, we will need to embed lyx.exe.manifest to lyx.exe +if use_vc: + env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % \ + env.File('$BUILDDIR/lyx.exe.manifest').path] + +# check socket libs +socket_libs = [] +if conf.CheckLib('socket'): + socket_libs.append('socket') +# nsl is the network services library and provides a +# transport-level interface to networking services. +if conf.CheckLib('nsl'): + socket_libs.append('nsl') + +# check available boost libs (since lyx1.4 does not use iostream) +boost_libs = [] +for lib in ['signals', 'regex', 'filesystem', 'iostreams']: + if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)): + boost_libs.append(lib) + +# check boost libraries +boost_opt = ARGUMENTS.get('boost', 'auto') +# check for system boost +lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib'] +inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include'] +# default to $BUILDDIR/libs (use None since this path will be added anyway) +boost_libpath = None +# here I assume that all libraries are in the same directory +if boost_opt == 'included': + boost_libraries = ['included_boost_%s' % x for x in boost_libs] + included_boost = True + env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost' +elif boost_opt == 'auto': + res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug') + # if not found, use local boost + if res[0] is None: + boost_libraries = ['included_boost_%s' % x for x in boost_libs] + included_boost = True + env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost' + else: + included_boost = False + (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res +elif boost_opt == 'system': + res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug') + if res[0] is None: + print "Can not find system boost libraries with version %s " % boost_version + print "Please supply a path through extra_lib_path and try again." + print "Or use boost=included to use included boost libraries." + Exit(2) + else: + included_boost = False + (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res + +if boost_libpath is not None: + env.AppendUnique(LIBPATH = [boost_libpath]) + + +env['ENABLE_NLS'] = env['nls'] + +if not env['ENABLE_NLS']: + intl_libs = [] + included_gettext = False +else: + # check gettext libraries + gettext_opt = ARGUMENTS.get('gettext', 'auto') + # check for system gettext + succ = False + if gettext_opt in ['auto', 'system']: + if conf.CheckLib('intl'): + included_gettext = False + intl_libs = ['intl'] + succ = True + else: # no found + if gettext_opt == 'system': + print "Can not find system gettext library" + print "Please supply a path through extra_lib_path and try again." + print "Or use gettext=included to use included gettext libraries." + Exit(2) + # now, auto and succ = false, or gettext=included + if not succ: + # we do not need to set LIBPATH now. + included_gettext = True + intl_libs = ['included_intl'] + +# +# check for msgfmt command +env['MSGFMT'] = conf.CheckCommand('msgfmt') + +# cygwin packaging requires the binaries to be stripped +if platform_name == 'cygwin': + env['STRIP'] = conf.CheckCommand('strip') + +# check uic and moc commands for qt frontends +if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \ + or conf.CheckCommand('moc') == None): + print 'uic or moc command is not found for frontend', frontend + Exit(1) + +# +# Customized builders +# +# install customized builders +env['BUILDERS']['substFile'] = Builder(action = utils.env_subst) + + +#---------------------------------------------------------- +# Generating config.h +#---------------------------------------------------------- +aspell_lib = 'aspell' +# assume that we use aspell, aspelld compiled for msvc +if platform_name == 'win32' and mode == 'debug' and use_vc: + aspell_lib = 'aspelld' + +# check the existence of config.h +config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h') +boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h') +# +print "Creating %s..." % boost_config_h +# +utils.createConfigFile(conf, + config_file = boost_config_h, + config_pre = '''/* boost/config.h. Generated by SCons. */ + +/* -*- 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 _BOOST_CONFIG_H +#define _BOOST_CONFIG_H +''', + headers = [ + ('ostream', 'HAVE_OSTREAM', 'cxx'), + ('locale', 'HAVE_LOCALE', 'cxx'), + ('sstream', 'HAVE_SSTREAM', 'cxx'), + #('newapis.h', 'HAVE_NEWAPIS_H', 'c'), + ], + custom_tests = [ + (env.has_key('assertions') and env['assertions'], + 'ENABLE_ASSERTIONS', + 'Define if you want assertions to be enabled in the code' + ), + ], + config_post = ''' + +#if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM) +# define USE_BOOST_FORMAT 1 +#else +# define USE_BOOST_FORMAT 0 +#endif + +#if !defined(ENABLE_ASSERTIONS) +# define BOOST_DISABLE_ASSERTS 1 +#endif +#define BOOST_ENABLE_ASSERT_HANDLER 1 + +#define BOOST_DISABLE_THREADS 1 +#define BOOST_NO_WSTRING 1 + +#ifdef __CYGWIN__ +# define BOOST_POSIX 1 +#endif + +#define BOOST_ALL_NO_LIB 1 + +#if defined(HAVE_NEWAPIS_H) +# define WANT_GETFILEATTRIBUTESEX_WRAPPER 1 +#endif + +#endif +''' +) +# +print "\nGenerating %s..." % config_h + +# AIKSAURUS_H_LOCATION +if (conf.CheckCXXHeader("Aiksaurus.h")): + aik_location = '' +elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")): + aik_location = '' +else: + aik_location = '' + +# determine headers to use +spell_opt = ARGUMENTS.get('spell', 'auto') +env['USE_ASPELL'] = False +env['USE_PSPELL'] = False +env['USE_ISPELL'] = False +if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib): + spell_engine = 'USE_ASPELL' +elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'): + spell_engine = 'USE_PSPELL' +elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'): + spell_engine = 'USE_ISPELL' +else: + spell_engine = None + +if spell_engine is not None: + env[spell_engine] = True +else: + if spell_opt == 'auto': + print "Warning: Can not locate any spell checker" + elif spell_opt != 'no': + print "Warning: Can not locate specified spell checker:", spell_opt + Exit(1) + +# check for iconv function/lib +if conf.CheckLib('iconv'): + env['ICONV_LIB'] = 'iconv' + env['HAVE_ICONV'] = True +elif conf.CheckLib('libiconv'): + env['ICONV_LIB'] = 'libiconv' + env['HAVE_ICONV'] = True +elif conf.CheckFunc('iconv_open'): + env['ICONV_LIB'] = None + env['HAVE_ICONV'] = True +else: + env['ICONV_LIB'] = None + env['HAVE_ICONV'] = False + +# check arg types of select function +(select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType() + +# +# create config.h +result = utils.createConfigFile(conf, + config_file = config_h, + config_pre = '''/* config.h. Generated by SCons. */ + +/* -*- 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 +''', + headers = [ + ('io.h', 'HAVE_IO_H', 'c'), + ('limits.h', 'HAVE_LIMITS_H', 'c'), + ('locale.h', 'HAVE_LOCALE_H', 'c'), + ('process.h', 'HAVE_PROCESS_H', 'c'), + ('stdlib.h', 'HAVE_STDLIB_H', 'c'), + ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'), + ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'), + ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'), + ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'), + ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'), + ('unistd.h', 'HAVE_UNISTD_H', 'c'), + ('utime.h', 'HAVE_UTIME_H', 'c'), + ('direct.h', 'HAVE_DIRECT_H', 'c'), + ('istream', 'HAVE_ISTREAM', 'cxx'), + ('ios', 'HAVE_IOS', 'cxx'), + ], + functions = [ + ('open', 'HAVE_OPEN', None), + ('close', 'HAVE_CLOSE', None), + ('popen', 'HAVE_POPEN', None), + ('pclose', 'HAVE_PCLOSE', None), + ('_open', 'HAVE__OPEN', None), + ('_close', 'HAVE__CLOSE', None), + ('_popen', 'HAVE__POPEN', None), + ('_pclose', 'HAVE__PCLOSE', None), + ('getpid', 'HAVE_GETPID', None), + ('_getpid', 'HAVE__GETPID', None), + ('mkdir', 'HAVE_MKDIR', None), + ('_mkdir', 'HAVE__MKDIR', None), + ('mktemp', 'HAVE_MKTEMP', None), + ('mkstemp', 'HAVE_MKSTEMP', None), + ('strerror', 'HAVE_STRERROR', None), + ('count', 'HAVE_STD_COUNT', ''' +#include +int count() +{ +char a[] = "hello"; +return std::count(a, a+5, 'l'); +} +'''), + ('getcwd', 'HAVE_GETCWD', None), + ('setenv', 'HAVE_SETENV', None), + ('putenv', 'HAVE_PUTENV', None), + ('fcntl', 'HAVE_FCNTL', None), + ], + types = [ + ('std::istreambuf_iterator', 'HAVE_DECL_ISTREAMBUF_ITERATOR', + '#include \n#include ') + ], + libs = [ + ('gdi32', 'HAVE_LIBGDI32'), + (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'), + ], + custom_tests = [ + (conf.CheckType('pid_t', includes='#include '), + 'HAVE_PID_T', + 'Define is sys/types.h does not have pid_t', + '', + '#define pid_t int', + ), + (conf.CheckCXXGlobalCstd(), + 'CXX_GLOBAL_CSTD', + 'Define if your C++ compiler puts C library functions in the global namespace' + ), + (conf.CheckMkdirOneArg(), + 'MKDIR_TAKES_ONE_ARG', + 'Define if mkdir takes only one argument.' + ), + (conf.CheckLC_MESSAGES(), + 'HAVE_LC_MESSAGES', + 'Define if your file defines LC_MESSAGES.' + ), + (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'), + (env['HAVE_ICONV'], + 'HAVE_ICONV', + 'Define to 1 if function iconv exists' + ), + (env['nls'], + 'ENABLE_NLS', + "Define to 1 if translation of program messages to the user's native anguage is requested.", + ), + (env['nls'] and not included_gettext, + 'HAVE_GETTEXT', + 'Define to 1 if using system gettext library' + ), + (env.has_key('warnings') and env['warnings'], + 'WITH_WARNINGS', + 'Define this if you want to see the warning directives put here and there by the developpers to get attention' + ), + (env.has_key('concept_checks') and env['concept_checks'], + '_GLIBCXX_CONCEPT_CHECKS', + 'libstdc++ concept checking' + ), + (env.has_key('stdlib_debug') and env['stdlib_debug'], + '_GLIBCXX_DEBUG', + 'libstdc++ debug mode' + ), + (env.has_key('stdlib_debug') and env['stdlib_debug'], + '_GLIBCXX_DEBUG_PEDANTIC', + 'libstdc++ pedantic debug mode' + ), + (os.name != 'nt', 'BOOST_POSIX', + 'Indicates to boost which API to use (posix or windows).' + ), + (spell_engine is not None, spell_engine, + 'Spell engine to use' + ), + ], + extra_items = [ + ('#define PACKAGE "%s%s"' % (package, program_suffix), + 'Name of package'), + ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport, + 'Define to the address where bug reports for this package should be sent.'), + ('#define PACKAGE_NAME "%s"' % package_name, + 'Define to the full name of this package.'), + ('#define PACKAGE_STRING "%s"' % package_string, + 'Define to the full name and version of this package.'), + ('#define PACKAGE_TARNAME "%s"' % package_tarname, + 'Define to the one symbol short name of this package.'), + ('#define PACKAGE_VERSION "%s"' % package_version, + 'Define to the version of this package.'), + ('#define BOOST_ALL_NO_LIB 1', + 'disable automatic linking of boost libraries.'), + ('#define USE_%s_PACKAGING 1' % packaging_method.upper(), + 'Packaging method'), + ('#define AIKSAURUS_H_LOCATION ' + aik_location, + 'Aiksaurus include file'), + ('#define SELECT_TYPE_ARG1 %s' % select_arg1, + "Define to the type of arg 1 for `select'."), + ('#define SELECT_TYPE_ARG234 %s' % select_arg234, + "Define to the type of arg 2, 3, 4 for `select'."), + ('#define SELECT_TYPE_ARG5 %s' % select_arg5, + "Define to the type of arg 5 for `select'."), + ], + config_post = '''/************************************************************ +** 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 + +#include <../boost/config.h> + +#endif +''' +) + +# these keys are needed in env +for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\ + 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', + 'ICONV_LIB', 'AIKSAURUS_LIB']: + # USE_ASPELL etc does not go through result + if result.has_key(key): + env[key] = result[key] + +# +# if nls=yes and gettext=included, create intl/config.h +# intl/libintl.h etc +# +intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h') +if env['nls'] and included_gettext: + # + print "Creating %s..." % intl_config_h + # + # create intl/config.h + result = utils.createConfigFile(conf, + config_file = intl_config_h, + config_pre = '''/* intl/config.h. Generated by SCons. */ + +/* -*- 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 +''', + headers = [ + ('unistd.h', 'HAVE_UNISTD_H', 'c'), + ('inttypes.h', 'HAVE_INTTYPES_H', 'c'), + ('string.h', 'HAVE_STRING_H', 'c'), + ('strings.h', 'HAVE_STRINGS_H', 'c'), + ('argz.h', 'HAVE_ARGZ_H', 'c'), + ('limits.h', 'HAVE_LIMITS_H', 'c'), + ('alloca.h', 'HAVE_ALLOCA_H', 'c'), + ('stddef.h', 'HAVE_STDDEF_H', 'c'), + ('stdint.h', 'HAVE_STDINT_H', 'c'), + ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'), + ], + functions = [ + ('getcwd', 'HAVE_GETCWD', None), + ('stpcpy', 'HAVE_STPCPY', None), + ('strcasecmp', 'HAVE_STRCASECMP', None), + ('strdup', 'HAVE_STRDUP', None), + ('strtoul', 'HAVE_STRTOUL', None), + ('alloca', 'HAVE_ALLOCA', None), + ('__fsetlocking', 'HAVE___FSETLOCKING', None), + ('mempcpy', 'HAVE_MEMPCPY', None), + ('__argz_count', 'HAVE___ARGZ_COUNT', None), + ('__argz_next', 'HAVE___ARGZ_NEXT', None), + ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None), + ('setlocale', 'HAVE_SETLOCALE', None), + ('tsearch', 'HAVE_TSEARCH', None), + ('getegid', 'HAVE_GETEGID', None), + ('getgid', 'HAVE_GETGID', None), + ('getuid', 'HAVE_GETUID', None), + ('wcslen', 'HAVE_WCSLEN', None), + ('asprintf', 'HAVE_ASPRINTF', None), + ('wprintf', 'HAVE_WPRINTF', None), + ('snprintf', 'HAVE_SNPRINTF', None), + ('printf', 'HAVE_POSIX_PRINTF', None), + ('fcntl', 'HAVE_FCNTL', None), + ], + types = [ + ('intmax_t', 'HAVE_INTMAX_T', None), + ('long double', 'HAVE_LONG_DOUBLE', None), + ('long long', 'HAVE_LONG_LONG', None), + ('wchar_t', 'HAVE_WCHAR_T', None), + ('wint_t', 'HAVE_WINT_T', None), + ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include '), + ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include '), + ], + libs = [ + ('c', 'HAVE_LIBC'), + ], + custom_tests = [ + (conf.CheckLC_MESSAGES(), + 'HAVE_LC_MESSAGES', + 'Define if your file defines LC_MESSAGES.' + ), + (conf.CheckIconvConst(), + 'ICONV_CONST', + 'Define as const if the declaration of iconv() needs const.', + '#define ICONV_CONST const', + '#define ICONV_CONST', + ), + (conf.CheckType('intmax_t', includes='#include ') or \ + conf.CheckType('intmax_t', includes='#include '), + 'HAVE_INTMAX_T', + "Define to 1 if you have the `intmax_t' type." + ), + (env.has_key('nls') and env['nls'], + 'ENABLE_NLS', + "Define to 1 if translation of program messages to the user's native anguage is requested.", + ), + (env['HAVE_ICONV'], + 'HAVE_ICONV', + 'Define to 1 if function iconv exists', + ), + ], + config_post = '#endif' + ) + + # these keys are needed in env + for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \ + 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']: + # USE_ASPELL etc does not go through result + if result.has_key(key): + env[key] = result[key] + +# this looks misplaced, but intl/libintl.h is needed by src/message.C +if env['nls'] and included_gettext: + # libgnuintl.h.in => libintl.h + env.Depends('$TOP_SRCDIR/intl/libintl.h', '$BUILDDIR/intl/config.h') + env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in') + env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h', + [Copy('$TARGET', '$SOURCE')]) + +# +# Finish auto-configuration +env = conf.Finish() + +#---------------------------------------------------------- +# Now set up our build process accordingly +#---------------------------------------------------------- + +# +# QT_LIB +# +# NOTE: Tool('qt') or Tool('qt4') will be loaded later +# in their respective directory and specialized env. +if frontend == 'qt2': + # note: env.Tool('qt') my set QT_LIB to qt + if platform_name == 'win32': + qt_libs = ['qt-mt3'] + else: + qt_libs = ['qt-mt'] + frontend_libs = qt_libs + + +if platform_name in ['win32', 'cygwin']: + # the final link step needs stdc++ to succeed under mingw + # FIXME: shouldn't g++ automatically link to stdc++? + if use_vc: + system_libs = ['ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll'] + else: + system_libs = ['shlwapi', 'stdc++', 'z'] +elif platform_name == 'cygwin' and env['X11']: + system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor', + 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv', + 'pthread', 'z'] +else: + system_libs = ['z'] + +libs = [ + ('HAVE_ICONV', env['ICONV_LIB']), + ('HAVE_LIBGDI32', 'gdi32'), + ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']), + ('USE_ASPELL', aspell_lib), + ('USE_ISPELL', 'ispell'), + ('USE_PSPELL', 'pspell'), +] + +for lib in libs: + if env[lib[0]] and lib[1] is not None: + system_libs.append(lib[1]) + +# +# Build parameters CPPPATH etc +# +if env['X11']: + env.AppendUnique(LIBPATH = ['/usr/X11R6/lib']) + +# +# boost: for boost header files +# BUILDDIR/common: for config.h +# TOP_SRCDIR/src: for support/* etc +# +env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src'] +# +# Separating boost directories from CPPPATH stops scons from building +# the dependency tree for boost header files, and effectively reduce +# the null build time of lyx from 29s to 16s. Since lyx may tweak local +# boost headers, this is only done for system boost headers. +if included_boost: + env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH']) +else: + if use_vc: + env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH']) + else: + env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH']) + +# for intl/config.h, intl/libintl.h and intl/libgnuintl.h +if env['nls'] and included_gettext: + env['CPPPATH'].append('$BUILDDIR/intl') +# +# QT_INC_PATH is not needed for *every* source file +env['CPPPATH'].remove(qt_inc_path) + +# +# A Link script for cygwin see +# http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html +# http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html +# for details +# +if platform_name == 'cygwin': + ld_script_path = '/tmp' + ld_script = utils.installCygwinLDScript(ld_script_path) + env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc', + '-Wl,--script,%s' % ld_script, '-Wl,-s']) + +# +# Report results +# +# fill in the version info +env['VERSION_INFO'] = '''Configuration + Host type: %s + Special build flags: %s + C Compiler: %s + C Compiler flags: %s %s + C++ Compiler: %s + C++ Compiler LyX flags: %s + C++ Compiler flags: %s %s + Linker flags: %s + Linker user flags: %s +Build info: + Builing directory: %s + Local library directory: %s + Libraries paths: %s + Boost libraries: %s + Frontend libraries: %s + System libraries: %s + include search path: %s +Frontend: + Frontend: %s + Packaging: %s + LyX dir: %s + LyX files dir: %s +''' % (platform_name, + env.subst('$CCFLAGS'), env.subst('$CC'), + env.subst('$CPPFLAGS'), env.subst('$CFLAGS'), + env.subst('$CXX'), env.subst('$CXXFLAGS'), + env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'), + env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'), + env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'), + str(env['LIBPATH']), str(boost_libraries), + str(frontend_libs), str(system_libs), str(env['CPPPATH']), + frontend, packaging_method, + prefix, env['LYX_DIR']) + +if frontend == 'qt2': + env['VERSION_INFO'] += ''' include dir: %s + library dir: %s + X11: %s +''' % (qt_inc_path, qt_lib_path, env['X11']) + +print env['VERSION_INFO'] + +# +# Mingw command line may be too short for our link usage, +# Here we use a trick from scons wiki +# http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32 +# +# I also would like to add logging (commands only) capacity to the +# spawn system. +logfile = env.get('logfile', default_log_file) +if logfile != '' or platform_name == 'win32': + import time + utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'), + info = '''# This is a log of commands used by scons to build lyx +# Time: %s +# Command: %s +# Info: %s +''' % (time.asctime(), ' '.join(sys.argv), + env['VERSION_INFO'].replace('\n','\n# ')) ) + + +# Cleanup stuff +# +# -h will print out help info +Help(opts.GenerateHelpText(env)) + + +#---------------------------------------------------------- +# Start building +#---------------------------------------------------------- +# this has been the source of problems on some platforms... +# I find that I need to supply it with full path name +env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign')) +# this usage needs further investigation. +#env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend)) + +print "Building all targets recursively" + +if env.has_key('rebuild'): + rebuild_targets = env['rebuild'].split(',') + if 'none' in rebuild_targets or 'no' in rebuild_targets: + rebuild_targets = [] + elif 'all' in rebuild_targets or 'yes' in rebuild_targets: + # None: let scons decide which components to build + # Forcing all components to be rebuilt is in theory not necessary + rebuild_targets = None +else: + rebuild_targets = None + +def libExists(libname): + ''' Check whether or not lib $LOCALLIBNAME/libname already exists''' + return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath) + +def appExists(apppath, appname): + ''' Check whether or not application already exists''' + return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath) + +targets = BUILD_TARGETS +# msvc need to pass full target name, so I have to look for path/lyx etc +build_lyx = targets == [] or True in ['lyx' in x for x in targets] \ + or 'install' in targets or 'all' in targets +build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets +build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets +build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']] +build_mathed = build_lyx or 'mathed' in targets +build_insets = build_lyx or 'insets' in targets +build_frontends = build_lyx or 'frontends' in targets +build_graphics = build_lyx or 'graphics' in targets +build_controllers = build_lyx or 'controllers' in targets +build_client = True in ['client' in x for x in targets] \ + or 'install' in targets or 'all' in targets +build_tex2lyx = True in ['tex2lyx' in x for x in targets] \ + or 'install' in targets or 'all' in targets +build_lyxbase = build_lyx or 'lyxbase' in targets +build_po = 'po' in targets or 'install' in targets or 'all' in targets +build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets +build_msvs_projects = use_vc and 'msvs_projects' in targets + + +# now, if rebuild_targets is specified, do not rebuild some targets +if rebuild_targets is not None: + # + def ifBuildLib(name, libname, old_value): + # explicitly asked to rebuild + if name in rebuild_targets: + return True + # else if not rebuild, and if the library already exists + elif libExists(libname): + return False + # do not change the original value + else: + return old_value + build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost) + build_intl = ifBuildLib('intl', 'included_intl', build_intl) + build_support = ifBuildLib('support', 'support', build_support) + build_mathed = ifBuildLib('mathed', 'mathed', build_mathed) + build_insets = ifBuildLib('insets', 'insets', build_insets) + build_frontends = ifBuildLib('frontends', 'frontends', build_frontends) + build_graphics = ifBuildLib('graphics', 'graphics', build_graphics) + build_controllers = ifBuildLib('controllers', 'controllers', build_controllers) + build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase) + build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2) + # + def ifBuildApp(name, appname, old_value): + # explicitly asked to rebuild + if name in rebuild_targets: + return True + # else if not rebuild, and if the library already exists + elif appExists(name, appname): + return False + # do not change the original value + else: + return old_value + build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx) + build_client = ifBuildApp('client', 'lyxclient', build_client) + +# sync frontend and frontend +if build_qt2: + frontend = 'qt2' + +if build_boost: + # + # boost libraries + # + # special builddir + env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0) + + boostenv = env.Copy() + # + # boost use its own config.h + boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths + boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG=""']) + + for lib in boost_libs: + print 'Processing files in boost/libs/%s/src...' % lib + boostlib = boostenv.StaticLibrary( + target = '$LOCALLIBPATH/included_boost_%s' % lib, + source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)] + ) + Alias('boost', boostlib) + + +if build_intl: + # + # intl + # + intlenv = env.Copy() + + print "Processing files in intl..." + + env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0) + + # we need the original C compiler for these files + intlenv['CC'] = C_COMPILER + intlenv['CCFLAGS'] = C_CCFLAGS + if use_vc: + intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX']) + # intl does not use global config.h + intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths + + intlenv.Append(CCFLAGS = [ + r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"', + r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"', + r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"', + '-DIN_LIBINTL', + '-DENABLE_RELOCATABLE=1', + '-DIN_LIBRARY', + r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"', + '-DNO_XMALLOC', + '-Dset_relocation_prefix=libintl_set_relocation_prefix', + '-Drelocate=libintl_relocate', + '-DDEPENDS_ON_LIBICONV=1', + '-DHAVE_CONFIG_H' + ] + ) + + intl = intlenv.StaticLibrary( + target = '$LOCALLIBPATH/included_intl', + LIBS = ['c'], + source = ['$BUILDDIR/intl/%s' % x for x in intl_files] + ) + Alias('intl', intl) + + +# +# Now, src code under src/ +# +env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0) + + +if build_support: + # + # src/support + # + print "Processing files in src/support..." + + env.Depends('$BUILDDIR/common/support/package.C', '$BUILDDIR/common/config.h') + env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in') + + support = env.StaticLibrary( + target = '$LOCALLIBPATH/support', + source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files] + ) + Alias('support', support) + + +if build_mathed: + # + # src/mathed + # + print "Processing files in src/mathed..." + # + mathed = env.StaticLibrary( + target = '$LOCALLIBPATH/mathed', + source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files] + ) + Alias('mathed', mathed) + + +if build_insets: + # + # src/insets + # + print "Processing files in src/insets..." + # + insets = env.StaticLibrary( + target = '$LOCALLIBPATH/insets', + source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files] + ) + Alias('insets', insets) + + +if build_frontends: + # + # src/frontends + # + print "Processing files in src/frontends..." + + frontends = env.StaticLibrary( + target = '$LOCALLIBPATH/frontends', + source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files] + ) + Alias('frontends', frontends) + + +if build_graphics: + # + # src/graphics + # + print "Processing files in src/graphics..." + + graphics = env.StaticLibrary( + target = '$LOCALLIBPATH/graphics', + source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files] + ) + Alias('graphics', graphics) + + +if build_controllers: + # + # src/frontends/controllers + # + print "Processing files in src/frontends/controllers..." + + controllers = env.StaticLibrary( + target = '$LOCALLIBPATH/controllers', + source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + ) + Alias('controllers', controllers) + + +# +# src/frontend/qt3/4 +# +if build_qt2: + env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0) + + print "Processing files in src/frontends/qt2..." + + qt2env = env.Copy() + # disable auto scan to speed up non build time + qt2env['QT_AUTOSCAN'] = 0 + qt2env['QT_MOCHPREFIX'] = '' + + # load qt2 tools + qt2env.Tool('qt') + qt2env['QT_UICDECLFLAGS'] = '-tr qt_' + qt2env['QT_UICIMPLFLAGS'] = '-tr qt_' + + qt2env.AppendUnique(CPPPATH = [ + '$BUILDDIR/common', + '$BUILDDIR/common/images', + '$BUILDDIR/common/frontends', + '$BUILDDIR/common/frontends/qt2', + '$BUILDDIR/common/frontends/controllers', + qt_inc_path] + ) + + qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in src_frontends_qt2_moc_files] + + # manually moc and uic files for better performance + qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files] + + qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \ + src_frontends_qt2_ui_files] + + qt2_uiced_cc_files = [] + for x in qt2_uiced_files: + qt2_uiced_cc_files.extend(x[1:]) + + qt2 = qt2env.StaticLibrary( + target = '$LOCALLIBPATH/qt2', + source = ['$BUILDDIR/common/frontends/qt2/%s' % x for x in src_frontends_qt2_files] \ + + qt2_moced_files + qt2_uiced_cc_files + ) + Alias('qt2', qt2) + + +if build_client: + # + # src/client + # + env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0) + + print "Processing files in src/client..." + + if env['HAVE_FCNTL']: + client = env.Program( + target = '$BUILDDIR/common/client/lyxclient', + LIBS = ['support'] + intl_libs + system_libs + + socket_libs + boost_libraries, + source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files] + \ + utils.createResFromIcon(env, 'lyx_32x32.ico', '$LOCALLIBPATH/client.rc') + + ) + Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]), + client, [Copy('$TARGET', '$SOURCE')])) + else: + client = None + Alias('client', client) +else: + if env['HAVE_FCNTL']: + # define client even if lyxclient is not built with rebuild=no + client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')] + else: + client = None + + +if build_tex2lyx: + # + # tex2lyx + # + print "Processing files in src/tex2lyx..." + + tex2lyx_env = env.Copy() + # + tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx']) + tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH']) + + for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C', + 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']: + env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file, + [Copy('$TARGET', '$SOURCE')]) + + tex2lyx = tex2lyx_env.Program( + target = '$BUILDDIR/common/tex2lyx/tex2lyx', + LIBS = ['support'] + boost_libraries + system_libs, + source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files] + \ + utils.createResFromIcon(tex2lyx_env, 'lyx_32x32.ico', '$LOCALLIBPATH/tex2lyx.rc') + ) + Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]), + tex2lyx, [Copy('$TARGET', '$SOURCE')])) + Alias('tex2lyx', tex2lyx) +else: + # define tex2lyx even if tex2lyx is not built with rebuild=no + tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')] + + +if build_lyxbase: + # + # src/ + # + print "Processing files in src..." + + env.Depends('$BUILDDIR/common/version.C', '$BUILDDIR/common/config.h') + env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in') + + if env.has_key('USE_ASPELL') and env['USE_ASPELL']: + src_post_files.append('aspell.C') + elif env.has_key('USE_PSPELL') and env['USE_PSPELL']: + src_post_files.append('pspell.C') + elif env.has_key('USE_ISPELL') and env['USE_ISPELL']: + src_post_files.append('ispell.C') + + # msvc requires at least one source file with main() + # so I exclude main.C from lyxbase + lyxbase_pre = env.StaticLibrary( + target = '$LOCALLIBPATH/lyxbase_pre', + source = ['$BUILDDIR/common/%s' % x for x in src_pre_files] + ) + lyxbase_post = env.StaticLibrary( + target = '$LOCALLIBPATH/lyxbase_post', + source = ["$BUILDDIR/common/%s" % x for x in src_post_files] + ) + Alias('lyxbase', lyxbase_pre) + Alias('lyxbase', lyxbase_post) + + +if build_lyx: + # + # Build lyx with given frontend + # + lyx = env.Program( + target = '$BUILDDIR/lyx', + source = ['$BUILDDIR/common/main.C'] + \ + utils.createResFromIcon(env, 'lyx_32x32.ico', '$LOCALLIBPATH/lyx.rc'), + LIBS = [ + 'lyxbase_pre', + 'mathed', + 'insets', + 'frontends', + frontend, + 'controllers', + 'graphics', + 'support', + 'lyxbase_post', + ] + + boost_libraries + + frontend_libs + + intl_libs + + socket_libs + + system_libs + ) + Alias('lyx', lyx) +else: + # define lyx even if lyx is not built with rebuild=no + lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')] + + +if build_msvs_projects: + def build_project(target, full_target = None, + src = [], inc = [], res = [], rebuildTargetOnly = True): + ''' build mavs project files + target: alias (correspond to directory name) + full_target: full path/filename of the target + src: source files + inc: include files + res: resource files + rebuildTargetOnly: whether or not only rebuild this target + + For non-debug-able targets like static libraries, target (alias) is + enough to build the target. For executable targets, msvs need to know + the full path to start debug them. + ''' + if rebuildTargetOnly: + cmds = 'rebuild='+target + else: + cmds = '' + if full_target is None: + build_target = target + else: + build_target = full_target + # project + proj = env.MSVSProject( + target = target + env['MSVSPROJECTSUFFIX'], + # this allows easy access to header files (along with source) + srcs = [env.subst(x) for x in src + inc], + incs = [env.subst('$TOP_SRCDIR/src/config.h')], + localincs = [env.subst(x) for x in inc], + resources = [env.subst(x) for x in res], + buildtarget = build_target, + cmdargs = cmds, + variant = 'Debug' + ) + Alias('msvs_projects', proj) + # + boost_src = [] + for lib in boost_libs: + boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)] + build_project('boost', src = boost_src) + # + build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files], + inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files]) + # + build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], + inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files]) + # + build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], + inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files]) + # + build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files], + inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files]) + # + build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files], + inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files]) + # + build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files], + inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files]) + # + build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files], + inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files]) + # + build_project('qt2', src = ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_files + src_frontends_qt2_moc_files], + inc = ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_header_files], + res = ['$TOP_SRCDIR/src/frontends/qt2/ui/%s' % x for x in src_frontends_qt2_ui_files]) + # + build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files], + inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files], + rebuildTargetOnly = False, + full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath) + # + build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files], + inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files], + rebuildTargetOnly = False, + full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath) + # + build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files], + inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files]) + # + if frontend == 'qt2': + build_project('lyx', + src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \ + ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \ + ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \ + ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \ + ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \ + ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \ + ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \ + ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_files + src_frontends_qt2_moc_files], + inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \ + ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \ + ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \ + ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \ + ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \ + ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \ + ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \ + ['$TOP_SRCDIR/src/frontends/qt2/%s' % x for x in src_frontends_qt2_header_files], + res = ['$TOP_SRCDIR/src/frontends/qt2/ui/%s' % x for x in src_frontends_qt2_ui_files], + rebuildTargetOnly = False, + full_target = File(env.subst('$BUILDDIR/lyx$PROGSUFFIX')).abspath) + + +if build_po: + # + # po/ + # + print 'Processing files in po...' + + import glob + # handle po files + # + # files to translate + transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po')) + # possibly *only* handle these languages + languages = None + if env.has_key('languages'): + languages = env.make_list(env['lanauges']) + # use defulat msgfmt + gmo_files = [] + if not env['MSGFMT']: + print 'msgfmt does not exist. Can not process po files' + else: + # create a builder + env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po') + # + for f in transfiles: + # get filename + fname = os.path.split(f)[1] + # country code + country = fname.split('.')[0] + # + if not languages or country in languages: + gmo_files.extend(env.Transfiles(f)) + + +if 'install' in targets: + # + # this part is a bit messy right now. Since scons will provide + # --DESTDIR option soon, at least the dest_dir handling can be + # removed later. + # + # how to join dest_dir and prefix + def joinPaths(path1, path2): + ''' join path1 and path2, do not use os.path.join because + under window, c:\destdir\d:\program is invalid ''' + if path1 == '': + return os.path.normpath(path2) + # separate drive letter + (drive, path) = os.path.splitdrive(os.path.normpath(path2)) + # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program + return os.path.join(os.path.normpath(path1), path[1:]) + # + # install to dest_dir/prefix + dest_dir = env.get('DESTDIR', '') + dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath) + # create the directory if needed + if not os.path.isdir(dest_prefix_dir): + try: + os.makedirs(dest_prefix_dir) + except: + pass + if not os.path.isdir(dest_prefix_dir): + print 'Can not create directory', dest_prefix_dir + Exit(3) + # + if env.has_key('exec_prefix'): + bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath) + else: + bin_dest_dir = os.path.join(dest_prefix_dir, 'bin') + if add_suffix: + share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix) + else: + share_dest_dir = os.path.join(dest_prefix_dir, share_dir) + man_dest_dir = os.path.join(dest_prefix_dir, man_dir) + locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir) + # + import glob + # + # install executables (lyxclient may be None) + # + if add_suffix: + version_suffix = program_suffix + else: + version_suffix = '' + # + # install lyx, if in release mode, try to strip the binary + if env.has_key('STRIP') and env['STRIP'] is not None and mode != 'debug': + # create a builder to strip and install + env['BUILDERS']['StripInstallAs'] = Builder(action='$STRIP $SOURCE -o $TARGET') + + # install executables + for (name, obj) in (('lyx', lyx), ('tex2lyx', tex2lyx), ('client', client)): + if obj is None: + continue + target_name = os.path.split(str(obj[0]))[1].replace(name, '%s%s' % (name, version_suffix)) + target = os.path.join(bin_dest_dir, target_name) + if env['BUILDERS'].has_key('StripInstallAs'): + env.StripInstallAs(target, obj) + else: + env.InstallAs(target, obj) + Alias('install', target) + # + # share/lyx + dirs = [] + for (dir,files) in [ + ('.', lib_files), + ('clipart', lib_clipart_files), + ('examples', lib_examples_files), + ('images', lib_images_files), + ('images/math', lib_images_math_files), + ('bind', lib_bind_files), + ('kbd', lib_kbd_files), + ('layouts', lib_layouts_files), + ('scripts', lib_scripts_files), + ('templates', lib_templates_files), + ('tex', lib_tex_files), + ('ui', lib_ui_files), + ('doc', lib_doc_files), + ('lyx2lyx', lib_lyx2lyx_files)]: + dirs.append(env.Install(os.path.join(share_dest_dir, dir), + [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files])) + Alias('install', dirs) + + if platform_name == 'cygwin': + # cygwin packaging requires a file /usr/share/doc/Cygwin/foot-vendor-suffix.README + Cygwin_README = os.path.join(dest_prefix_dir, 'share', 'doc', 'Cygwin', + '%s-%s.README' % (package, package_cygwin_version)) + env.InstallAs(Cygwin_README, + os.path.join(env.subst('$TOP_SRCDIR'), 'README.cygwin')) + Alias('install', Cygwin_README) + # also a directory /usr/share/doc/lyx for README etc + Cygwin_Doc = os.path.join(dest_prefix_dir, 'share', 'doc', package) + env.Install(Cygwin_Doc, [os.path.join(env.subst('$TOP_SRCDIR'), x) for x in \ + ['INSTALL', 'README', 'README.Cygwin', 'RELEASE-NOTES', 'COPYING', 'ANNOUNCE']]) + Alias('install', Cygwin_Doc) + # cygwin fonts also need to be installed + Cygwin_fonts = os.path.join(share_dest_dir, 'fonts') + env.Install(Cygwin_fonts, + [env.subst('$TOP_SRCDIR/development/Win32/packaging/bakoma/%s' % file) \ + for file in win32_bakoma_fonts]) + Alias('install', Cygwin_fonts) + # we also need a post installation script + tmp_script = utils.installCygwinPostinstallScript('/tmp') + postinstall_path = os.path.join(dest_dir, 'etc', 'postinstall') + env.Install(postinstall_path, tmp_script) + Alias('install', postinstall_path) + + # man + env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'), + env.subst('$TOP_SRCDIR/lyx.man')) + env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'), + env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man')) + env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'), + env.subst('$TOP_SRCDIR/src/client/lyxclient.man')) + Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for + x in ['lyx', 'tex2lyx', 'lyxclient']]) + # locale files? + # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo + for gmo in gmo_files: + lan = os.path.split(str(gmo))[1].split('.')[0] + dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo') + env.InstallAs(dest_file, gmo) + Alias('install', dest_file) + + +Default('lyx') +Alias('all', ['lyx', 'client', 'tex2lyx'])