gettext support, fast_start option, scons all, mingw bug fix and some cleanup for the scons build system

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13849 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2006-05-15 20:35:01 +00:00
parent 479abc6efd
commit e94889a041
3 changed files with 783 additions and 670 deletions

View File

@ -13,18 +13,18 @@ import os, sys
Import('env') Import('env')
targets = env['BUILD_TARGETS'] targets = env['BUILD_TARGETS']
build_lyx = (targets == [] or 'lyx' in targets or 'install' in targets) build_lyx = (targets == [] or 'lyx' in targets or 'install' in targets or 'all' in targets)
if env['INCLUDED_BOOST'] or 'boost' in targets:
# #
# boost libraries # boost libraries
# #
if env['INCLUDED_BOOST'] or 'boost' in targets: # special builddir
env.BuildDir('$BUILDDIR/boost', '$TOP_SRC_DIR/boost/libs', duplicate = 0) env.BuildDir('$BUILDDIR/boost', '$TOP_SRC_DIR/boost/libs', duplicate = 0)
boostenv = env.Copy() boostenv = env.Copy()
boostenv.Append(CCFLAGS = '-DBOOST_USER_CONFIG="<config.h>"') boostenv.AppendUnique(CCFLAGS = '-DBOOST_USER_CONFIG="<config.h>"')
# for config.h
boostenv.Append(CPPPATH = ['$TOP_SRC_DIR/src'])
print 'Processing files in boost/libs/filesystem/src...' print 'Processing files in boost/libs/filesystem/src...'
@ -83,21 +83,19 @@ if env['INCLUDED_BOOST'] or 'boost' in targets:
Alias('boost', signals) Alias('boost', signals)
Alias('boost', iostreams) Alias('boost', iostreams)
# #
# Now, src code under src/ # Now, src code under src/
# #
env.BuildDir('$BUILDDIR/common', '$TOP_SRC_DIR/src', duplicate = 0) env.BuildDir('$BUILDDIR/common', '$TOP_SRC_DIR/src', duplicate = 0)
if build_lyx or True in [x in targets for x in ['supports', 'client', 'tex2lyx']]:
# #
# src/support # src/support
# #
if build_lyx or True in [x in targets for x in ['supports', 'client', 'tex2lyx']]:
print "Processing files in src/support" print "Processing files in src/support"
env.Append(CPPPATH = ['.'])
env['SUBST_KEYS'] = ['LYX_DIR', 'LOCALEDIR', 'TOP_SRCDIR', 'PROGRAM_SUFFIX'] env['SUBST_KEYS'] = ['LYX_DIR', 'LOCALEDIR', 'TOP_SRCDIR', 'PROGRAM_SUFFIX']
env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRC_DIR/src/support/package.C.in') env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRC_DIR/src/support/package.C.in')
@ -136,11 +134,11 @@ if build_lyx or True in [x in targets for x in ['supports', 'client', 'tex2lyx']
) )
Alias('supports', supports) Alias('supports', supports)
if build_lyx or 'mathed' in targets:
# #
# src/mathed # src/mathed
# #
if build_lyx or 'mathed' in targets:
print "Processing files in src/mathed" print "Processing files in src/mathed"
mathed = env.StaticLibrary( mathed = env.StaticLibrary(
@ -290,7 +288,6 @@ if build_lyx or 'frontends' in targets:
# #
# src/frontends # src/frontends
# #
print "Processing files in src/frontends" print "Processing files in src/frontends"
frontends = env.StaticLibrary( frontends = env.StaticLibrary(
@ -314,7 +311,6 @@ if build_lyx or 'graphics' in targets:
# #
# src/graphics # src/graphics
# #
print "Processing files in src/graphics" print "Processing files in src/graphics"
graphics = env.StaticLibrary( graphics = env.StaticLibrary(
@ -340,7 +336,6 @@ if build_lyx or 'controllers' in targets:
# #
# src/frontends/controllers # src/frontends/controllers
# #
print "Processing files in src/frontends/controllers" print "Processing files in src/frontends/controllers"
controllers = env.StaticLibrary( controllers = env.StaticLibrary(
@ -397,6 +392,7 @@ if build_lyx or 'controllers' in targets:
) )
Alias('controllers', controllers) Alias('controllers', controllers)
# #
# src/frontend/qt3/4 # src/frontend/qt3/4
# #
@ -417,18 +413,19 @@ if frontend == 'qt3':
print "Processing files in src/frontends/qt3" print "Processing files in src/frontends/qt3"
qt3env = env.Copy() qt3env = env.Copy()
# disable auto scan to speed up non build time
qt3env['QT_AUTOSCAN'] = 0
# load qt3 tools # load qt3 tools
qt3env.Tool('qt') qt3env.Tool('qt')
qt3env.Append(CPPPATH = [ qt3env.AppendUnique(CPPPATH = [
'$BUILDDIR/common', '$BUILDDIR/common',
'$BUILDDIR/common/images',
'$BUILDDIR/common/frontends', '$BUILDDIR/common/frontends',
'$BUILDDIR/common/frontends/qt3', '$BUILDDIR/common/frontends/qt3',
'$BUILDDIR/common/images',
'$BUILDDIR/common/frontends/controllers', '$BUILDDIR/common/frontends/controllers',
'$BUILDDIR/common/frontends/qt3', '$QT_INC_PATH']
'$QT_INC_DIR']
) )
qt3_ui_files = Split(''' qt3_ui_files = Split('''
@ -503,7 +500,6 @@ if frontend == 'qt3':
QWrapDialogBase.ui QWrapDialogBase.ui
''') ''')
qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split(''' qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
BulletsModule.C BulletsModule.C
emptytable.C emptytable.C
@ -564,14 +560,15 @@ if frontend == 'qt3':
validators.C validators.C
''')] ''')]
# under windows, because of the .C/.c confusion # manually moc and uic files for better performance
# moc_files are not moced automatically. # (stop autoscan, 13:20s->12:50s :-)
# I am doing it manually here, until lyx changes
# file extension from .C to .cpp
qt3_moced_files = []
if os.name == 'nt' or sys.platform == 'cygwin':
qt3_moced_files = [qt3env.Moc(x.replace('.C', '.h')) for x in qt3_moc_files] qt3_moced_files = [qt3env.Moc(x.replace('.C', '.h')) for x in qt3_moc_files]
qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in qt3_ui_files]
qt3_uiced_cc_files = []
for x in qt3_uiced_files:
qt3_uiced_cc_files.extend(x[1:])
qt3 = qt3env.StaticLibrary( qt3 = qt3env.StaticLibrary(
target = '$LOCALLIBPATH/qt3', target = '$LOCALLIBPATH/qt3',
source = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split(''' source = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
@ -636,8 +633,7 @@ if frontend == 'qt3':
qscreen.C qscreen.C
qt_helpers.C qt_helpers.C
''')] + ''')] +
qt3_moc_files + qt3_moced_files + qt3_moc_files + qt3_moced_files + qt3_uiced_cc_files
['$BUILDDIR/common/frontends/qt3/ui/' + x for x in qt3_ui_files]
) )
Alias('qt3', qt3) Alias('qt3', qt3)
@ -646,6 +642,7 @@ elif frontend == 'qt4':
print "Processing files in src/frontends/qt4" print "Processing files in src/frontends/qt4"
qt4env = env.Copy() qt4env = env.Copy()
qt4env['QT_AUTOSCAN'] = 0
# local qt4 toolset from # local qt4 toolset from
# http://www.iua.upf.es/~dgarcia/Codders/sconstools.html # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
@ -656,7 +653,7 @@ elif frontend == 'qt4':
qt4env.Tool('qt4', [env['SCONS_DIR']]) qt4env.Tool('qt4', [env['SCONS_DIR']])
qt4env.EnableQt4Modules(env['QT_LIB'], debug = False) qt4env.EnableQt4Modules(env['QT_LIB'], debug = False)
qt4env.Append(CPPPATH = [ qt4env.AppendUnique(CPPPATH = [
'$BUILDDIR/common', '$BUILDDIR/common',
'$BUILDDIR/common/images', '$BUILDDIR/common/images',
'$BUILDDIR/common/frontends', '$BUILDDIR/common/frontends',
@ -678,7 +675,7 @@ elif frontend == 'qt4':
'-Winvalid-pch'] '-Winvalid-pch']
) )
qt4_ui_files = Split(''' qt4_ui_files = ['$BUILDDIR/common/frontends/qt4/ui/%s' % x for x in Split('''
BiblioUi BiblioUi
BranchesUi BranchesUi
BulletsUi BulletsUi
@ -748,9 +745,9 @@ elif frontend == 'qt4':
QURLUi QURLUi
QVSpaceUi QVSpaceUi
QWrapUi QWrapUi
''') ''')]
qt4_moc_files = Split(''' qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
BulletsModule.C BulletsModule.C
emptytable.C emptytable.C
FileDialog_private.C FileDialog_private.C
@ -811,15 +808,9 @@ elif frontend == 'qt4':
QLToolbar.C QLToolbar.C
socket_callback.C socket_callback.C
validators.C validators.C
''') ''') ]
# qt4_source_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
# Compile resources
#
for x in qt4_ui_files:
qt4env.Uic4('$BUILDDIR/common/frontends/qt4/ui/' + x)
qt4_source_files = Split('''
QDialogView.C QDialogView.C
Alert_pimpl.C Alert_pimpl.C
Dialogs.C Dialogs.C
@ -881,18 +872,29 @@ elif frontend == 'qt4':
qfont_metrics.C qfont_metrics.C
qscreen.C qscreen.C
qt_helpers.C qt_helpers.C
''') ''')]
#
# Compile resources
#
resources = [qt4env.Uic4(x) for x in qt4_ui_files]
#
# moc qt4_moc_files
#
qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
# if the moced files are included in the .C file
# the Flatten(...) part will not be needed
qt4 = qt4env.StaticLibrary( qt4 = qt4env.StaticLibrary(
target = '$LOCALLIBPATH/qt4', target = '$LOCALLIBPATH/qt4',
LIBS = qt4env['QT_LIB'], LIBS = qt4env['QT_LIB'],
source = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in qt4_source_files] + \ source = qt4_source_files + qt4_moc_files + Flatten(qt4_moced_files)
["$BUILDDIR/common/frontends/qt4/%s" % x for x in qt4_moc_files]
) )
Alias('qt4', qt4) Alias('qt4', qt4)
if 'client' in targets or 'install' in targets: if 'client' in targets or 'install' in targets or 'all' in targets:
# #
# src/client # src/client
# #
@ -900,6 +902,7 @@ if 'client' in targets or 'install' in targets:
print "Processing files in src/client" print "Processing files in src/client"
try:
client = env.Program( client = env.Program(
target = '$BUILDDIR/common/client/lyxclient', target = '$BUILDDIR/common/client/lyxclient',
LIBS = env['BOOST_LIBRARIES'] + env['SOCKET_LIBS'] + ['supports'], LIBS = env['BOOST_LIBRARIES'] + env['SOCKET_LIBS'] + ['supports'],
@ -913,10 +916,13 @@ if 'client' in targets or 'install' in targets:
) )
Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]), Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
client, [Copy('$TARGET', '$SOURCE')])) client, [Copy('$TARGET', '$SOURCE')]))
except:
print "Building of program lyxclient failed"
client = None
Alias('client', client) Alias('client', client)
if 'tex2lyx' in targets or 'install' in targets: if 'tex2lyx' in targets or 'install' in targets or 'all' in targets:
# #
# tex2lyx # tex2lyx
# #
@ -925,7 +931,7 @@ if 'tex2lyx' in targets or 'install' in targets:
tex2lyx_env = env.Copy() tex2lyx_env = env.Copy()
# the order is important here. # the order is important here.
tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx']) tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
tex2lyx_env.Append(LIBPATH = ['#$LOCALLIBPATH']) tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/FloatList.C', '$TOP_SRC_DIR/src/FloatList.C') tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/FloatList.C', '$TOP_SRC_DIR/src/FloatList.C')
tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/Floating.C', '$TOP_SRC_DIR/src/Floating.C') tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/Floating.C', '$TOP_SRC_DIR/src/Floating.C')
@ -938,6 +944,7 @@ if 'tex2lyx' in targets or 'install' in targets:
tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/lyxlex.C', '$TOP_SRC_DIR/src/lyxlex.C') tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/lyxlex.C', '$TOP_SRC_DIR/src/lyxlex.C')
tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/lyxlex_pimpl.C', '$TOP_SRC_DIR/src/lyxlex_pimpl.C') tex2lyx_env.fileCopy('$BUILDDIR/common/tex2lyx/lyxlex_pimpl.C', '$TOP_SRC_DIR/src/lyxlex_pimpl.C')
try:
tex2lyx = tex2lyx_env.Program( tex2lyx = tex2lyx_env.Program(
target = '$BUILDDIR/common/tex2lyx/tex2lyx', target = '$BUILDDIR/common/tex2lyx/tex2lyx',
LIBS = ['supports'] + env['BOOST_LIBRARIES'] + env['SYSTEM_LIBS'], LIBS = ['supports'] + env['BOOST_LIBRARIES'] + env['SYSTEM_LIBS'],
@ -964,6 +971,9 @@ if 'tex2lyx' in targets or 'install' in targets:
) )
Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]), Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
tex2lyx, [Copy('$TARGET', '$SOURCE')])) tex2lyx, [Copy('$TARGET', '$SOURCE')]))
except:
print "Building of program tex2lyx failed"
tex2lyx = None
Alias('tex2lyx', tex2lyx) Alias('tex2lyx', tex2lyx)
@ -1114,6 +1124,7 @@ if build_lyx or 'lyx' in targets:
# #
# Build lyx with given frontend # Build lyx with given frontend
# #
try:
lyx = env.Program( lyx = env.Program(
target = '$BUILDDIR/$frontend/lyx', target = '$BUILDDIR/$frontend/lyx',
source = [], source = [],
@ -1137,17 +1148,59 @@ if build_lyx or 'lyx' in targets:
target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend) target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx, Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
[Copy('$TARGET', '$SOURCE')])) [Copy('$TARGET', '$SOURCE')]))
except:
print "Building of program lyx failed"
lyx = None
raise
Alias('lyx', lyx) Alias('lyx', lyx)
if 'install' in targets: if 'po' in targets or 'install' in targets or 'all' in targets:
# #
# This does not look clever right now. I am using the basic # po/
# install builder of scons instead of fancier wiki solutions #
# with the hope that scons can finish standarding this soon. print 'Processing files in po...'
import glob
# handle po files
#
# files to translate
transfiles = glob.glob(os.path.join(env.subst('$TOP_SRC_DIR'), 'po', '*.po'))
# possibly *only* handle these languages
languages = None
if env.has_key('languages'):
languages = env.make_list(env['lanauges'])
# use defulat msgfmt
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')
#
gmo_files = []
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:
# create the directory if needed
if not os.path.isdir(env['PREFIX']):
try:
os.makedirs(env['PREFIX'])
except:
pass
if not os.path.isdir(env['PREFIX']):
print 'Can not create directory', env['PREFIX']
Exit(3)
# #
import glob import glob
#
# windows: $PREFIX/Resources # windows: $PREFIX/Resources
# others: $PREDIX/share/lyx # others: $PREDIX/share/lyx
share_dir = env['SHARE_DIR'] share_dir = env['SHARE_DIR']
@ -1159,7 +1212,7 @@ if 'install' in targets:
locale_dir = env['LOCALE_DIR'] locale_dir = env['LOCALE_DIR']
def install(dest, src): def install(dest, src):
''' recusive installation of src ''' ''' recusive installation of src to dest '''
# separate file and directory # separate file and directory
files = filter(os.path.isfile, [x for x in src]) files = filter(os.path.isfile, [x for x in src])
dirs = filter(os.path.isdir, [x for x in src]) dirs = filter(os.path.isdir, [x for x in src])
@ -1172,17 +1225,16 @@ if 'install' in targets:
glob.glob(os.path.join(dir, '*'))) ) glob.glob(os.path.join(dir, '*'))) )
return ins_dir return ins_dir
# #
# executables # executables (some of them may be none)
env.Install(env['BIN_DIR'], [lyx, tex2lyx, client]) env.Install(env['BIN_DIR'], filter(lambda x: x != None, [lyx, tex2lyx, client]))
Alias('install', env['BIN_DIR']) Alias('install', env['BIN_DIR'])
# #
# share/lyx # share/lyx
dirs = install(env['SHARE_DIR'], dirs = install(env['SHARE_DIR'],
[env.subst('$TOP_SRC_DIR/lib/') + file for file in ['configure.py', 'encodings', [env.subst('$TOP_SRC_DIR/lib/') + file for file in ['configure.py', 'encodings',
'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages', 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
'lyxrc.example', 'syntax.default', \ 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
'images', 'layouts', 'scripts', 'templates', \ 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
) )
Alias('install', dirs) Alias('install', dirs)
# man # man
@ -1194,7 +1246,14 @@ if 'install' in targets:
env.subst('$TOP_SRC_DIR/src/client/lyxclient.man')) env.subst('$TOP_SRC_DIR/src/client/lyxclient.man'))
Alias('install', [os.path.join(env['MAN_DIR'], x) for Alias('install', [os.path.join(env['MAN_DIR'], x) for
x in ['lyx.1', 'tex2lyx.1', 'lyxclient.1']]) x in ['lyx.1', 'tex2lyx.1', 'lyxclient.1']])
# locale files?
# ru.gmo ==> ru/LC_MESSAGES/lyx.mo
for gmo in gmo_files:
lan = os.path.split(str(gmo))[1].split('.')[0]
dest_file = os.path.join(env['LOCALE_DIR'], lan, 'LC_MESSAGES', 'lyx.mo')
env.InstallAs(dest_file, gmo)
Alias('install', dest_file)
Default('lyx') Default('lyx')
Alias('all', ['lyx', 'client', 'tex2lyx', 'po'])

View File

@ -10,22 +10,22 @@
# #
# #
# This is a scons based building system for lyx, you can use it as follows: # This is a scons based building system for lyx, you can use it as follows:
# (after of course installation of scons from www.scons.org)
# #
# $ cd development/scons # $ cd development/scons
# $ scons [options] [targets] # $ scons [options] [targets]
# or: # or:
# $ scons -f development/scons/SConstruct [options] [targets] # $ scons -f development/scons/SConstruct [options] [targets]
# # and:
# After compiling, you can install lyx by
# $ scons [prefix=.] install # $ scons [prefix=.] install
# #
# Where: # Where:
# * targets can be one or more of lyx, tex2lyx, client, default to lyx # * targets can be one or more of lyx, tex2lyx, client, po, install.
# * options: use scons -h for details about parameters, the most important # default to lyx, you can use 'scons all' to build all targets except
# for install
# * options: use scons -h for details about options, the most important
# one is frontend=qt3|qt4. # one is frontend=qt3|qt4.
# * qt3 is used by default on linux, cygwin and mac # - qt3 is used by default on linux, cygwin and mac
# * qt4 is used by default on win32/mingw # - qt4 is used by default on win32/mingw
# #
# File layouts (Important): # File layouts (Important):
# * Unless you specify builddir=dir, building will happen # * Unless you specify builddir=dir, building will happen
@ -33,29 +33,29 @@
# * $BUILDDIR has subdirectories # * $BUILDDIR has subdirectories
# libs: all intermediate libraries # libs: all intermediate libraries
# boost: boost libraries, if boost=included is used # boost: boost libraries, if boost=included is used
# qt3: build result # qt3/4: frontend-specific objects
# * lyx executable will be in directories like debug/linux-qt3 # * executables will be copied to $BUILDDIR/
# #
# Hints: # Hints:
# * scons fast_start=yes
# If env.cache exists, bypass all tests and use existing src/config.h
#
# * scons --config=force # * scons --config=force
# force re-configuration (use scons -H for details) # force re-configuration (use scons -H for details)
# #
# * check config.log to see why config has failed # * check config.log to see why config has failed
# #
# * use extra_inc_path, extra_lib_path, qt_dir, qt_inc_path # * use extra_inc_path, extra_lib_path, qt_dir, qt_inc_path
# qt_lib_path to help locate qt and other libraries # qt_lib_path to help locate qt and other libraries.
# (there are extra_inc_path1, extra_lib_path1 for now) # There are also extra_inc_path1, extra_lib_path1 if you need to spacify
# more than one extra paths.
# #
# * (Important) use scons logfile=logfile.log to enable command line # * executed commands will be logged in scons_lyx.log. You can use logfile=
# logging. (default is no logging) # option to save log to another file.
# #
# Notes: # Notes:
# * Currently, all scons does is building lyx in
# $LYXROOT/$mode/$build_dir/
# where $mode is debug or release, $build_dir is the build_dir name
# listed above
# #
# * scons install etc may be added later. Interested contributors can follow # * scons dist etc may be added later. Interested contributors can follow
# http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/AccumulateBuilder # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/AccumulateBuilder
# or # or
# http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/DistTarBuilder # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/DistTarBuilder
@ -71,14 +71,12 @@
# features. # features.
# #
import os, sys import os, sys, copy, cPickle
# config/scons_utils.py defines a few utility function # config/scons_utils.py defines a few utility function
sys.path.append('config') sys.path.append('config')
import scons_utils as utils import scons_utils as utils
SetOption('implicit_cache', 1)
#---------------------------------------------------------- #----------------------------------------------------------
# Required runtime environment # Required runtime environment
#---------------------------------------------------------- #----------------------------------------------------------
@ -114,18 +112,15 @@ PACKAGE_NAME = 'LyX'
PACKAGE_TARNAME = 'lyx' PACKAGE_TARNAME = 'lyx'
PACKAGE_STRING = '%s %s' % (PACKAGE_NAME, PACKAGE_VERSION) PACKAGE_STRING = '%s %s' % (PACKAGE_NAME, PACKAGE_VERSION)
PROGRAM_SUFFIX = '' PROGRAM_SUFFIX = ''
# various cache/log files
default_log_file = 'scons_lyx.log' default_log_file = 'scons_lyx.log'
env_cache_file = 'env.cache'
# FIXME: what is this? (They are used in src/support/package.C.in
LOCALEDIR = "../locale/"
LYX_DIR = "/usr/local/share/lyx"
# platform dependent default build_dir and other settings #----------------------------------------------------------
# # platform dependent settings
# I know, somebody would say: #----------------------------------------------------------
# This is TOTALLY wrong! Everything should be automatically
# determined.
#
if os.name == 'nt': if os.name == 'nt':
platform_name = 'win32' platform_name = 'win32'
default_frontend = 'qt4' default_frontend = 'qt4'
@ -135,13 +130,13 @@ if os.name == 'nt':
default_pch_opt = False default_pch_opt = False
default_with_x = False default_with_x = False
spell_checker = 'auto' spell_checker = 'auto'
# FIXME: I need to know what exactly is boost_posix # boost_posix indicates to boost which API to use (posix or windows).
# EF: It indicates to boost which API to use (posix or windows).
# If not specified, boost tries to figure out by itself, but it may fail. # If not specified, boost tries to figure out by itself, but it may fail.
boost_posix = False boost_posix = False
packaging_method = 'windows' packaging_method = 'windows'
default_prefix = 'c:/program files/lyx'
share_dir = 'Resources' share_dir = 'Resources'
man_dir = 'Resouces/man/man1' man_dir = 'Resources/man/man1'
locale_dir = 'Resources/locale' locale_dir = 'Resources/locale'
elif os.name == 'posix' and sys.platform != 'cygwin': elif os.name == 'posix' and sys.platform != 'cygwin':
platform_name = sys.platform platform_name = sys.platform
@ -153,6 +148,7 @@ elif os.name == 'posix' and sys.platform != 'cygwin':
default_with_x = True default_with_x = True
boost_posix = True boost_posix = True
packaging_method = 'posix' packaging_method = 'posix'
default_prefix = '/usr/local/'
share_dir = 'share/lyx' share_dir = 'share/lyx'
man_dir = 'man/man1' man_dir = 'man/man1'
locale_dir = 'share/locale' locale_dir = 'share/locale'
@ -166,6 +162,7 @@ elif os.name == 'posix' and sys.platform == 'cygwin':
default_with_x = True default_with_x = True
boost_posix = True boost_posix = True
packaging_method = 'posix' packaging_method = 'posix'
default_prefix = '/usr/local/'
share_dir = 'share/lyx' share_dir = 'share/lyx'
man_dir = 'man/man1' man_dir = 'man/man1'
locale_dir = 'share/locale' locale_dir = 'share/locale'
@ -178,9 +175,11 @@ elif os.name == 'darwin':
default_pch_opt = False default_pch_opt = False
default_with_x = False default_with_x = False
boost_posix = True boost_posix = True
packaging_method = 'msc' packaging_method = 'mac'
# FIXME: where to install?
default_prefix = '/usr/local/'
share_dir = 'Resources' share_dir = 'Resources'
man_dir = 'Resouces/man/man1' man_dir = 'Resources/man/man1'
locale_dir = 'Resources/locale' locale_dir = 'Resources/locale'
else: # unsupported system else: # unsupported system
platform_name = 'others' platform_name = 'others'
@ -192,68 +191,55 @@ else: # unsupported system
default_with_x = True default_with_x = True
boost_posix = False boost_posix = False
packaging_method = 'posix' packaging_method = 'posix'
default_prefix = '/usr/local/'
share_dir = 'share/lyx' share_dir = 'share/lyx'
man_dir = 'man/man1' man_dir = 'man/man1'
locale_dir = 'share/locale' locale_dir = 'share/locale'
#--------------------------------------------------------- #---------------------------------------------------------
# Handling options # Handling options
#---------------------------------------------------------- #----------------------------------------------------------
# Note that if you set the options via the command line,
# they will be remembered in the file 'options.cache'
# #
# NOTE: the scons people are trying to fix scons so that
# options like --prefix will be accepted. Right now,
# we have to use the KEY=VALUE style of scons
#
if os.path.isfile('options.cache'):
print "Getting options from auto-saved options.cache..."
print open('options.cache').read()
if os.path.isfile('config.py'): if os.path.isfile('config.py'):
print "Getting options from config.py..." print "Getting options from config.py..."
print open('config.py').read() print open('config.py').read()
opts = Options(['options.cache', 'config.py']) opts = Options(['config.py'])
opts.AddOptions( opts.AddOptions(
# frontend, # frontend,
EnumOption('frontend', 'Main GUI', EnumOption('frontend', 'Main GUI', default_frontend,
default_frontend,
allowed_values = ('xform', 'qt3', 'qt4', 'gtk') ), allowed_values = ('xform', 'qt3', 'qt4', 'gtk') ),
# debug or release build # debug or release build
EnumOption('mode', 'Building method', default_build_mode, EnumOption('mode', 'Building method', default_build_mode,
allowed_values = ('debug', 'release') ), allowed_values = ('debug', 'release') ),
# boost libraries # boost libraries
EnumOption('boost', EnumOption('boost',
'Use included, system boost library, or try sytem first.', 'Use included, system boost library, or try sytem boost first.',
default_boost_opt, default_boost_opt,
allowed_values = ( allowed_values = (
'auto', # detect boost, if not found, use included 'auto', # detect boost, if not found, use included
'included', # always use included boost 'included', # always use included boost
'system', # always use system boost, fail if can not find 'system', # always use system boost, fail if can not find
) ), ) ),
# FIXME: not implemented yet.
EnumOption('gettext', EnumOption('gettext',
'Use included, system gettext library, or try sytem first', 'Use included, system gettext library, or try sytem gettext first',
default_gettext_opt, default_gettext_opt,
allowed_values = ( allowed_values = (
'auto', # detect gettext, if not found, use included 'auto', # detect gettext, if not found, use included
'included', # always use included gettext 'included', # always use included gettext
'system', # always use system gettext, fail if can not find 'system', # always use system gettext, fail if can not find
) ), ) ),
# FIXME: I am not allowed to use '' as default, '.' is not good either. #
PathOption('qt_dir', 'Path to qt directory', '.'), EnumOption('spell', 'Choose spell checker to use.', 'auto',
PathOption('qt_include_path', 'Path to qt include directory', '.'), allowed_values = ('aspell', 'pspell', 'ispell', 'auto') ),
PathOption('qt_lib_path', 'Path to qt library directory', '.'), #
BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
# FIXME: I do not know how pch is working. Ignore this option now. # FIXME: I do not know how pch is working. Ignore this option now.
BoolOption('pch', '(NA) Whether or not use pch', default_pch_opt), BoolOption('pch', '(NA) Whether or not use pch', default_pch_opt),
# FIXME: Not implemented yet. # FIXME: Not implemented yet.
BoolOption('version_suffix', '(NA) Whether or not add version suffix', False), BoolOption('version_suffix', '(NA) Whether or not add version suffix', False),
# build directory, will replace build_dir if set
PathOption('build_dir', 'Build directory', '.'),
# extra include and libpath
PathOption('extra_inc_path', 'Extra include path', '.'),
PathOption('extra_lib_path', 'Extra library path', '.'),
PathOption('extra_inc_path1', 'Extra include path', '.'),
PathOption('extra_lib_path1', 'Extra library path', '.'),
# enable assertion, (config.h has ENABLE_ASSERTIOS # enable assertion, (config.h has ENABLE_ASSERTIOS
BoolOption('assertions', 'Use assertions', True), BoolOption('assertions', 'Use assertions', True),
# enable warning, (config.h has WITH_WARNINGS) # enable warning, (config.h has WITH_WARNINGS)
@ -264,34 +250,47 @@ opts.AddOptions(
BoolOption('nls', '(NA) Whether or not use native language support', False), BoolOption('nls', '(NA) Whether or not use native language support', False),
# FIXME: not implemented # FIXME: not implemented
BoolOption('profile', '(NA) Whether or not enable profiling', False), BoolOption('profile', '(NA) Whether or not enable profiling', False),
#
PathOption('prefix', 'install architecture-independent files in PREFIX', '.'),
#
PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', '.'),
# FIXME: not implemented # FIXME: not implemented
BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False), BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False),
# using x11? # using x11?
BoolOption('X11', 'Use x11 windows system', default_with_x), BoolOption('X11', 'Use x11 windows system', default_with_x),
# FIXME: not implemented # FIXME: not implemented
BoolOption('libintl', '(NA) Use libintl library', False), BoolOption('libintl', '(NA) Use libintl library', False),
#
PathOption('qt_dir', 'Path to qt directory', None),
#
PathOption('qt_include_path', 'Path to qt include directory', None),
#
PathOption('qt_lib_path', 'Path to qt library directory', None),
# build directory, will use $mode if not set
PathOption('build_dir', 'Build directory', None),
# extra include and libpath
PathOption('extra_inc_path', 'Extra include path', None),
#
PathOption('extra_lib_path', 'Extra library path', None),
#
PathOption('extra_inc_path1', 'Extra include path', None),
#
PathOption('extra_lib_path1', 'Extra library path', None),
# can be set to a non-existing directory
('prefix', 'install architecture-independent files in PREFIX', None),
#
PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
# FIXME: not implemented # FIXME: not implemented
PathOption('intl_prefix', '(NA) Path to intl library', '.'), PathOption('intl_prefix', '(NA) Path to intl library', None),
# log file # log file
('logfile', 'save commands (not outputs) to logfile', default_log_file), ('logfile', 'save commands (not outputs) to logfile', default_log_file),
# Path to aikasurus # Path to aikasurus
PathOption('aikasurus_path', 'Path to aikasurus library', '.'), PathOption('aikasurus_path', 'Path to aikasurus library', None),
# # environment variable can be set as options. (DO NOT set defaults)
EnumOption('spell', 'Choose spell checker to use.', 'auto', ('CC', '$CC', None),
allowed_values = ('aspell', 'pspell', 'ispell', 'auto') ), ('LINK', '$LINK', None),
# environment variable can be set as options ('CPP', '$CPP', None),
('CC', '$CC', 'gcc'), ('CXX', '$CXX', None),
('CPP', '$CPP', 'gcc -E'), ('CXXCPP', '$CXXCPP', None),
('CXX', '$CXX', 'g++'), ('CCFLAGS', '$CCFLAGS', None),
('CXXCPP', '$CXXCPP', 'g++ -E'), ('CPPFLAGS', '$CPPFLAGS', None),
('CCFLAGS', '$CCFLAGS', ''), ('LDFLAGS', '$LDFLAGS', None),
('CPPFLAGS', '$CPPFLAGS', ''),
('CPPPATH', '$CPPPATH', ''),
('LDFLAGS', '$LDFLAGS', ''),
) )
@ -304,16 +303,35 @@ env = Environment(options = opts)
# Determine the frontend to use, which may be loaded # Determine the frontend to use, which may be loaded
# from option cache # from option cache
frontend = env.get('frontend', default_frontend) frontend = env.get('frontend', default_frontend)
# make sure the key exists
env['frontend'] = frontend
#
use_X11 = env.get('X11', default_with_x) use_X11 = env.get('X11', default_with_x)
# set environment since I do not really like ENV = os.environ # whether or not use current config.h, and cached tests
if env['fast_start'] and os.path.isfile(env_cache_file):
fast_start = True
SetOption('implicit_cache', 1)
cache_file = open(env_cache_file)
env_cache = cPickle.load(cache_file)
cache_file.close()
print '------------ fast_start mode --------------------'
print ' Use cached test results and current config.h'
print ' use fast_start=no to override'
print '-------------------------------------------------'
else:
fast_start = False
SetOption('implicit_cache', 0)
env_cache = {}
# set individual variables since I do not really like ENV = os.environ
env['ENV']['PATH'] = os.environ.get('PATH') env['ENV']['PATH'] = os.environ.get('PATH')
env['ENV']['HOME'] = os.environ.get('HOME') env['ENV']['HOME'] = os.environ.get('HOME')
env['TOP_SRC_DIR'] = TOP_SRC_DIR env['TOP_SRC_DIR'] = TOP_SRC_DIR
env['SCONS_DIR'] = SCONS_DIR env['SCONS_DIR'] = SCONS_DIR
# install to current directory by default # install to default_prefix by default
env['PREFIX'] = env.get('prefix', '.') env['PREFIX'] = env.get('prefix', default_prefix)
if env.has_key('exec_prefix') and env['exec_prefix'] != '.': if env.has_key('exec_prefix'):
env['BIN_DIR'] = env['exec_prefix'] env['BIN_DIR'] = env['exec_prefix']
else: else:
env['BIN_DIR'] = os.path.join(env['PREFIX'], 'bin') env['BIN_DIR'] = os.path.join(env['PREFIX'], 'bin')
@ -329,50 +347,36 @@ def getEnvVariable(env, name):
# first try command line argument (override environment settings) # first try command line argument (override environment settings)
if ARGUMENTS.has_key(name) and ARGUMENTS[name].strip() != '': if ARGUMENTS.has_key(name) and ARGUMENTS[name].strip() != '':
env[name] = ARGUMENTS[name] env[name] = ARGUMENTS[name]
# then try environment variable # then use environment default
elif os.environ.has_key(name) and os.environ[name].strip() != '': elif os.environ.has_key(name) and os.environ[name].strip() != '':
env[name] = os.environ[name] env[name] = os.environ[name]
print "Acquiring varaible %s from system environment: %s" % (name, env[name]) print "Acquiring varaible %s from system environment: %s" % (name, env[name])
# finally, env['CC'] etc is set to the default values of Options.
# and env['CPP'] etc does not exist
getEnvVariable(env, 'CC') getEnvVariable(env, 'CC')
getEnvVariable(env, 'LINK')
getEnvVariable(env, 'CPP') getEnvVariable(env, 'CPP')
getEnvVariable(env, 'CXX') getEnvVariable(env, 'CXX')
getEnvVariable(env, 'CXXCPP') getEnvVariable(env, 'CXXCPP')
getEnvVariable(env, 'CCFLAGS') getEnvVariable(env, 'CCFLAGS')
getEnvVariable(env, 'CXXFLAGS') getEnvVariable(env, 'CXXFLAGS')
getEnvVariable(env, 'CPPFLAGS') getEnvVariable(env, 'CPPFLAGS')
getEnvVariable(env, 'CPPPATH')
getEnvVariable(env, 'LDFLAGS') getEnvVariable(env, 'LDFLAGS')
# 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
#
# Solaris seems to use gcc for the last step as well, so, to
# make sure everyone uses a C++ compiler, linker, I do this for
# all platform
#
# just to be safe
if env.has_key('CXX') and env['CXX'] != '':
env['CC'] = env['CXX']
env['LINK'] = env['CXX']
else:
env['CC'] = 'g++'
env['LINK'] = 'g++'
# #
# frontend, mode, BUILDDIR and LOCALLIBPATH=BUILDDIR/libs # frontend, mode, BUILDDIR and LOCALLIBPATH=BUILDDIR/libs
# #
env['frontend'] = frontend
env['mode'] = env.get('mode', default_build_mode) env['mode'] = env.get('mode', default_build_mode)
# lyx will be built to $build/build_dir so it is possible # lyx will be built to $build/build_dir so it is possible
# to build multiple build_dirs using the same source # to build multiple build_dirs using the same source
# $mode can be debug or release # $mode can be debug or release
if ARGUMENTS.has_key('build_dir'): if env.has_key('build_dir') and env['build_dir']:
build_dir = ARGUMENTS['build_dir'] build_dir = env['build_dir']
env['BUILDDIR'] = build_dir env['BUILDDIR'] = build_dir
else: else:
# Determine the name of the build (platform+frontend # Determine the name of the build $mode
env['BUILDDIR'] = '#' + env['mode'] env['BUILDDIR'] = '#' + env['mode']
# all built libraries will go to build_dir/libs # all built libraries will go to build_dir/libs
# (This is different from the make file approach) # (This is different from the make file approach)
@ -382,20 +386,16 @@ env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
# #
# QTDIR, QT_LIB_PATH, QT_INC_PATH # QTDIR, QT_LIB_PATH, QT_INC_PATH
# #
if platform_name == 'win32': if env.has_key('qt_dir') and env['qt_dir']:
env.Tool('mingw')
if env.has_key('qt_dir') and env['qt_dir'] != '.':
env['QTDIR'] = env['qt_dir'] env['QTDIR'] = env['qt_dir']
# add path to the qt tools # add path to the qt tools
env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')]) env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
env.AppendUnique(CPPPATH = [os.path.join(env['qt_dir'], 'include')])
# set environment so that moc etc can be found even if its path is not set properly # set environment so that moc etc can be found even if its path is not set properly
env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin')) env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
else: else:
env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3') env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
if env.has_key('qt_lib_path') and env['qt_lib_path'] != '.': if env.has_key('qt_lib_path') and env['qt_lib_path']:
env['QT_LIB_PATH'] = env['qt_lib_path'] env['QT_LIB_PATH'] = env['qt_lib_path']
else: else:
env['QT_LIB_PATH'] = '$QTDIR/lib' env['QT_LIB_PATH'] = '$QTDIR/lib'
@ -403,26 +403,28 @@ env.AppendUnique(LIBPATH = ['$QT_LIB_PATH'])
# qt4 seems to be using pkg_config # qt4 seems to be using pkg_config
env.PrependENVPath('PKG_CONFIG_PATH', env.subst('$QT_LIB_PATH')) env.PrependENVPath('PKG_CONFIG_PATH', env.subst('$QT_LIB_PATH'))
if env.has_key('qt_inc_path') and env['qt_inc_path'] != '.': if env.has_key('qt_inc_path') and env['qt_inc_path']:
env['QT_INC_PATH'] = env['qt_inc_path'] env['QT_INC_PATH'] = env['qt_inc_path']
elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')): elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
env['QT_INC_PATH'] = '$QTDIR/include' env['QT_INC_PATH'] = '$QTDIR/include'
else: # have to guess else: # have to guess
env['QT_INC_PATH'] = '/usr/include/$frontend/' env['QT_INC_PATH'] = '/usr/include/$frontend/'
# Note that this CPPPATH is for testing only
# it will be removed before calling SConscript
env.AppendUnique(CPPPATH = env['QT_INC_PATH']) env.AppendUnique(CPPPATH = env['QT_INC_PATH'])
# #
# extra_inc_path and extra_lib_path # extra_inc_path and extra_lib_path
# #
if env.has_key('extra_inc_path'): if env.has_key('extra_inc_path') and env['extra_inc_path']:
env.AppendUnique(CPPPATH = [env['extra_inc_path']]) env.AppendUnique(CPPPATH = [env['extra_inc_path']])
if env.has_key('extra_lib_path'): if env.has_key('extra_lib_path') and env['extra_lib_path']:
env.AppendUnique(LIBPATH = [env['extra_lib_path']]) env.AppendUnique(LIBPATH = [env['extra_lib_path']])
if env.has_key('extra_inc_path1'): if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
env.AppendUnique(CPPPATH = [env['extra_inc_path1']]) env.AppendUnique(CPPPATH = [env['extra_inc_path1']])
if env.has_key('extra_lib_path1'): if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
env.AppendUnique(LIBPATH = [env['extra_lib_path1']]) env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
if env.has_key('aikasurus_path'): if env.has_key('aikasurus_path') and env['aikasurus_path']:
env.AppendUnique(LIBPATH = [env['aikasurus_path']]) env.AppendUnique(LIBPATH = [env['aikasurus_path']])
# #
@ -430,6 +432,22 @@ if env.has_key('aikasurus_path'):
# but it is required to do the tests. # but it is required to do the tests.
if platform_name == 'win32': if platform_name == 'win32':
env.AppendUnique(CPPPATH = ['#c:/MinGW/include']) env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
env.Tool('mingw')
# 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
#
# Note that this step has to be after env.Tool('mingw') step
# since env.Tool('mingw') will set env['CC'] etc.
#
if env.has_key('CXX') and env['CXX']:
env['CC'] = env['CXX']
env['LINK'] = env['CXX']
else:
env['CC'] = 'g++'
env['LINK'] = 'g++'
#---------------------------------------------------------- #----------------------------------------------------------
# Autoconf business # Autoconf business
@ -445,29 +463,35 @@ conf = Configure(env,
'CheckStdCount' : utils.checkStdCount, 'CheckStdCount' : utils.checkStdCount,
'CheckSelectArgType' : utils.checkSelectArgType, 'CheckSelectArgType' : utils.checkSelectArgType,
'CheckBoostLibraries' : utils.checkBoostLibraries, 'CheckBoostLibraries' : utils.checkBoostLibraries,
'CheckMsgFmt' : utils.checkMsgFmt,
} }
) )
# pkg-config? (if not, we use hard-coded options) # pkg-config? (if not, we use hard-coded options)
if not fast_start:
if conf.CheckPkgConfig('0.15.0'): if conf.CheckPkgConfig('0.15.0'):
env['HAS_PKG_CONFIG'] = True env['HAS_PKG_CONFIG'] = True
else: else:
print 'pkg-config >= 0.1.50 is not found' print 'pkg-config >= 0.1.50 is not found'
env['HAS_PKG_CONFIG'] = False env['HAS_PKG_CONFIG'] = False
env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
else:
env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
# zlib? This is required. # zlib? This is required. (fast_start assumes the existance of zlib)
if not conf.CheckLibWithHeader('z', 'zlib.h', 'C'): if not fast_start and not conf.CheckLibWithHeader('z', 'zlib.h', 'C'):
print 'Did not find libz or zlib.h, exiting!' print 'Did not find libz or zlib.h, exiting!'
Exit(1) Exit(1)
# qt libraries? # qt libraries?
if not fast_start:
# #
# qt3 does not use pkg_config # qt3 does not use pkg_config
if env['frontend'] == 'qt3': if frontend == 'qt3':
if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'): if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
print 'Did not find qt libraries, exiting!' print 'Did not find qt libraries, exiting!'
Exit(1) Exit(1)
elif env['frontend'] == 'qt4': elif frontend == 'qt4':
succ = False succ = False
# first: try pkg_config # first: try pkg_config
if env['HAS_PKG_CONFIG']: if env['HAS_PKG_CONFIG']:
@ -495,16 +519,23 @@ elif env['frontend'] == 'qt4':
print 'Did not find qt libraries, exiting!' print 'Did not find qt libraries, exiting!'
Exit(1) Exit(1)
# check socket libs # check socket libs
if not fast_start:
env['SOCKET_LIBS'] = [] env['SOCKET_LIBS'] = []
if conf.CheckLib('socket'): if conf.CheckLib('socket'):
env['SOCKET_LIBS'].append('socket') env['SOCKET_LIBS'].append('socket')
# EF: This is the network services library and provides a # nsl is the network services library and provides a
# transport-level interface to networking services. # transport-level interface to networking services.
if conf.CheckLib('nsl'): if conf.CheckLib('nsl'):
env['SOCKET_LIBS'].append('nsl') env['SOCKET_LIBS'].append('nsl')
env_cache['SOCKET_LIBS'] = env['SOCKET_LIBS']
else:
env['SOCKET_LIBS'] = env_cache['SOCKET_LIBS']
if not fast_start:
# check boost libraries # check boost libraries
boost_opt = ARGUMENTS.get('boost', default_boost_opt) boost_opt = ARGUMENTS.get('boost', default_boost_opt)
# check for system boost # check for system boost
@ -515,31 +546,44 @@ if boost_opt in ['auto', 'system']:
reg = conf.CheckBoostLibraries('boost_regex', pathes) reg = conf.CheckBoostLibraries('boost_regex', pathes)
fil = conf.CheckBoostLibraries('boost_filesystem', pathes) fil = conf.CheckBoostLibraries('boost_filesystem', pathes)
ios = conf.CheckBoostLibraries('boost_iostreams', pathes) ios = conf.CheckBoostLibraries('boost_iostreams', pathes)
# if any them is not found # if any of them is not found
if ('' in [sig[0], reg[0], fil[0], ios[0]]): if ('' in [sig[0], reg[0], fil[0], ios[0]]):
if boost_opt == 'system': if boost_opt == 'system':
print "Can not find system boost libraries" print "Can not find system boost libraries"
print "Please supply a path through extra_lib_path" print "Please supply a path through extra_lib_path and try again."
print "and try again." print "Or use boost=included to use included boost libraries."
Exit(2) Exit(2)
else: else:
env['BOOST_LIBRARIES'] = [sig[1], reg[1], fil[1], ios[1]] env['BOOST_LIBRARIES'] = [sig[1], reg[1], fil[1], ios[1]]
# assume all boost libraries are in the same path... # assume all boost libraries are in the same path...
print sig[0]
env.AppendUnique(LIBPATH = [sig[0]]) env.AppendUnique(LIBPATH = [sig[0]])
env['INCLUDED_BOOST'] = False env['INCLUDED_BOOST'] = False
succ = True succ = True
# now, auto and succ = false, or included # now, auto and succ = false, or boost=included
if not succ: if not succ:
# we do not need to set LIBPATH now. # we do not need to set LIBPATH now.
env['BOOST_LIBRARIES'] = ['boost_signals', 'boost_regex', env['BOOST_LIBRARIES'] = ['boost_signals', 'boost_regex',
'boost_filesystem', 'boost_iostreams'] 'boost_filesystem', 'boost_iostreams']
env['INCLUDED_BOOST'] = True env['INCLUDED_BOOST'] = True
env_cache['BOOST_LIBRARIES'] = env['BOOST_LIBRARIES']
env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
else:
env['BOOST_LIBRARIES'] = env_cache['BOOST_LIBRARIES']
env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
# #
# Building config.h # check for msgfmt command
# if not fast_start:
env['MSGFMT'] = conf.CheckMsgFmt()
env_cache['MSGFMT'] = env['MSGFMT']
else:
env['MSGFMT'] = env_cache['MSGFMT']
#----------------------------------------------------------
# Generating config.h
#----------------------------------------------------------
if not fast_start:
print "Generating ", utils.config_h, "..." print "Generating ", utils.config_h, "..."
# I do not handle all macros in src/config.h.in, rather I am following a list # I do not handle all macros in src/config.h.in, rather I am following a list
@ -687,28 +731,44 @@ if spell_engine in ['auto', 'aspell'] and \
conf.CheckLib('aspell'): conf.CheckLib('aspell'):
utils.addToConfig('#define USE_ASPELL 1', TOP_SRC_DIR) utils.addToConfig('#define USE_ASPELL 1', TOP_SRC_DIR)
env['USE_ASPELL'] = True env['USE_ASPELL'] = True
env['USE_PSPELL'] = False
env['USE_ISPELL'] = False
env['EXTRA_LIBS'].append('aspell') env['EXTRA_LIBS'].append('aspell')
spell_detected = True spell_detected = True
elif spell_engine in ['auto', 'pspell'] and \ elif spell_engine in ['auto', 'pspell'] and \
conf.CheckLib('pspell'): conf.CheckLib('pspell'):
utils.addToConfig('#define USE_PSPELL 1', TOP_SRC_DIR) utils.addToConfig('#define USE_PSPELL 1', TOP_SRC_DIR)
env['USE_ASPELL'] = False
env['USE_PSPELL'] = True env['USE_PSPELL'] = True
env['USE_ISPELL'] = False
env['EXTRA_LIBS'].append('pspell') env['EXTRA_LIBS'].append('pspell')
spell_detected = True spell_detected = True
elif spell_engine in ['auto', 'ispell'] and \ elif spell_engine in ['auto', 'ispell'] and \
conf.CheckLib('ispell'): conf.CheckLib('ispell'):
utils.addToConfig('#define USE_ISPELL 1', TOP_SRC_DIR) utils.addToConfig('#define USE_ISPELL 1', TOP_SRC_DIR)
env['USE_ASPELL'] = False
env['USE_PSPELL'] = False
env['USE_ISPELL'] = True env['USE_ISPELL'] = True
env['EXTRA_LIBS'].append('ispell') env['EXTRA_LIBS'].append('ispell')
spell_detected = True spell_detected = True
if not spell_detected: if not spell_detected:
env['USE_ASPELL'] = False
env['USE_PSPELL'] = False
env['USE_ISPELL'] = False
# FIXME: can lyx work without an spell engine # FIXME: can lyx work without an spell engine
if spell_engine == 'auto': if spell_engine == 'auto':
print "Warning: Can not locate any spell checker" print "Warning: Can not locate any spell checker"
else: else:
print "Warning: Can not locate specified spell checker:", spell_engine print "Warning: Can not locate specified spell checker:", spell_engine
# env['EXTRA_LIBS'] will be modified later, so a unique copy is needed
# NOTE that we do *not* save qt_libs in environment.
env_cache['EXTRA_LIBS'] = copy.copy(env['EXTRA_LIBS'])
env_cache['USE_ASPELL'] = env['USE_ASPELL']
env_cache['USE_PSPELL'] = env['USE_PSPELL']
env_cache['USE_ISPELL'] = env['USE_ISPELL']
# USE_POSIX_PACKAGING # USE_POSIX_PACKAGING
# USE_MACOSX_PACKAGING # USE_MACOSX_PACKAGING
# USE_WINDOWS_PACKAGING # USE_WINDOWS_PACKAGING
@ -762,6 +822,13 @@ utils.addToConfig('#define SELECT_TYPE_ARG5 %s' % arg5, TOP_SRC_DIR)
# WANT_GETFILEATTRIBUTESEX_WRAPPER # WANT_GETFILEATTRIBUTESEX_WRAPPER
utils.endConfigH(TOP_SRC_DIR) utils.endConfigH(TOP_SRC_DIR)
else:
# only a few variables need to be rescanned
env['EXTRA_LIBS'] = copy.copy(env_cache['EXTRA_LIBS'])
env['USE_ASPELL'] = env_cache['USE_ASPELL']
env['USE_PSPELL'] = env_cache['USE_PSPELL']
env['USE_ISPELL'] = env_cache['USE_ISPELL']
# #
# Finish auto-configuration # Finish auto-configuration
env = conf.Finish() env = conf.Finish()
@ -779,35 +846,39 @@ try:
if frontend == 'qt3': if frontend == 'qt3':
# note: env.Tool('qt') my set QT_LIB to qt # note: env.Tool('qt') my set QT_LIB to qt
env['QT_LIB'] = 'qt-mt' env['QT_LIB'] = 'qt-mt'
env['EXTRA_LIBS'] += ['qt-mt'] env['EXTRA_LIBS'].append('qt-mt')
if platform_name == 'cygwin' and use_X11: if platform_name == 'cygwin' and use_X11:
env['EXTRA_LIBS'] += ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor', env['EXTRA_LIBS'].extend(['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
'pthread'] 'pthread'])
env.AppendUnique(LIBPATH = ['/usr/X11R6/lib']) env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
elif frontend == 'qt4': elif frontend == 'qt4':
# local qt4 toolset from
# http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
if platform_name == "win32": if platform_name == "win32":
env['QT_LIB'] = ['QtCore4', 'QtGui4'] env['QT_LIB'] = ['QtCore4', 'QtGui4']
else: else:
env['QT_LIB'] = ['QtCore', 'QtGui'] env['QT_LIB'] = ['QtCore', 'QtGui']
env['EXTRA_LIBS'] += [x for x in env['QT_LIB']] env['EXTRA_LIBS'] += env['QT_LIB']
except: except:
print "Can not locate qt tools" print "Can not locate qt tools"
print "What I get is " print "What I get is "
print " QTDIR: ", env['QTDIR'] print " QTDIR: ", env['QTDIR']
if platform_name in ['win32', 'cygwin']: if platform_name in ['win32', 'cygwin']:
env['SYSTEM_LIBS'] = ['shlwapi', 'z'] # the final link step needs stdc++ to succeed under mingw
# FIXME: shouldn't g++ automatically link to stdc++?
env['SYSTEM_LIBS'] = ['shlwapi', 'z', 'stdc++']
else: else:
env['SYSTEM_LIBS'] = ['z'] env['SYSTEM_LIBS'] = ['z']
# #
# Build parameters CPPPATH etc # Build parameters CPPPATH etc
# #
# boost is always in # boost is always in, src is needed for config.h
env.AppendUnique(CPPPATH = ['$TOP_SRC_DIR/boost', '$TOP_SRC_DIR/src']) #
# Note that previously added QT_DIR/include etc is removed
# they will be added when processing for example src/qt3
env['CPPPATH'] = ['$TOP_SRC_DIR/boost', '$TOP_SRC_DIR/src']
# TODO: add (more) appropriate compiling options (-DNDEBUG etc) # TODO: add (more) appropriate compiling options (-DNDEBUG etc)
# for debug/release mode # for debug/release mode
@ -830,7 +901,7 @@ env['BUILDERS']['fileCopy'] = Builder(action = utils.env_filecopy)
# http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
# for details # for details
# #
if platform_name == 'cygwin' and env['frontend'] == 'qt3': if platform_name == 'cygwin':
ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++' ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
ld_script = utils.installCygwinLDScript(ld_script_path) ld_script = utils.installCygwinLDScript(ld_script_path)
env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc', env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
@ -840,9 +911,11 @@ if platform_name == 'cygwin' and env['frontend'] == 'qt3':
# Report results # Report results
# #
# src/support/package.C.in needs the following to replace # src/support/package.C.in needs the following to replace
env['LYX_DIR'] = LYX_DIR # LYX_ABS_INSTALLED_DATADIR (e.g. /usr/local/lyx/share/lyx)
env['LOCALEDIR'] = LOCALEDIR env['LYX_DIR'] = env['SHARE_DIR']
env['TOP_SRCDIR'] = str(Dir('#')) # LYX_ABS_INSTALLED_LOCALEDIR
env['LOCALEDIR'] = env['LOCALE_DIR']
env['TOP_SRCDIR'] = env['TOP_SRC_DIR']
env['PROGRAM_SUFFIX'] = PROGRAM_SUFFIX env['PROGRAM_SUFFIX'] = PROGRAM_SUFFIX
# needed by src/version.C.in => src/version.C # needed by src/version.C.in => src/version.C
env['PACKAGE_VERSION'] = PACKAGE_VERSION env['PACKAGE_VERSION'] = PACKAGE_VERSION
@ -886,6 +959,7 @@ if env['frontend'] in ['qt3', 'qt4']:
X11: %s X11: %s
''' % (env.subst('$QT_INC_PATH'), env.subst('$QT_LIB_PATH'), use_X11) ''' % (env.subst('$QT_INC_PATH'), env.subst('$QT_LIB_PATH'), use_X11)
if not fast_start:
print env['VERSION_INFO'] print env['VERSION_INFO']
# #
@ -895,7 +969,7 @@ print env['VERSION_INFO']
# #
# I also would like to add logging (commands only) capacity to the # I also would like to add logging (commands only) capacity to the
# spawn system. # spawn system.
logfile = ARGUMENTS.get('logfile', default_log_file) logfile = env.get('logfile', default_log_file)
if logfile != '' or platform_name == 'win32': if logfile != '' or platform_name == 'win32':
import time import time
utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'), utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
@ -910,18 +984,23 @@ if logfile != '' or platform_name == 'win32':
# #
# Cleanup stuff # Cleanup stuff
# #
# save options
opts.Save('options.cache', env)
# -h will print out help info # -h will print out help info
Help(opts.GenerateHelpText(env)) Help(opts.GenerateHelpText(env))
# save environment settings (for fast_start option)
cache_file = open(env_cache_file, 'w')
cPickle.dump(env_cache, cache_file)
cache_file.close()
#---------------------------------------------------------- #----------------------------------------------------------
# Start building # Start building
#---------------------------------------------------------- #----------------------------------------------------------
Export('env') Export('env')
SConsignFile(os.path.abspath('%s/sconsign' % env['BUILDDIR'])) # this has been the source of problem on some platforms...
# needs more testing
env.SConsignFile('%s/.sconsign' % env['BUILDDIR'][1:])
# this usage needs further investigation.
#env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
env['BUILD_TARGETS'] = BUILD_TARGETS env['BUILD_TARGETS'] = BUILD_TARGETS

View File

@ -292,40 +292,15 @@ def checkBoostLibraries(conf, lib, pathes):
return ('','') return ('','')
import SCons.Node def checkMsgFmt(conf):
def processLang(env, folder): ''' check the existence of command msgfmt '''
""" Process translations (.po files) in a po/ dir conf.Message('Checking for gettext command msgfmt...')
This is copied from KDE knetstats-1.5/admin/kde.py res = conf.TryAction('msgfmt --help')
conf.Result(res[0])
FIXME: imcomplete if res[0]:
""" return 'msgfmt'
import glob
dir=SCons.Node.FS.default_fs.Dir(folder).srcnode()
fld=dir.srcnode()
tmptransfiles = glob.glob(str(fld)+'/*.po')
transfiles=[]
if env.has_key('_BUILDDIR_'):
bdir=env['_BUILDDIR_']
for dir in env.make_list(tmptransfiles):
transfiles.append( env.join(bdir, dir) )
else: else:
transfiles=tmptransfiles return None
env['MSGFMT'] = 'msgfmt'
env['BUILDERS']['Transfiles']=SCons.Builder.Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
languages=None
# FIXME: KDE has this ARGS thing...
#if env['ARGS'] and env['ARGS'].has_key('languages'):
# languages=env.make_list(env['ARGS']['languages'])
mydir=SCons.Node.FS.default_fs.Dir('.')
for f in transfiles:
fname=f.replace(mydir.abspath, '')
file=SCons.Node.FS.default_fs.File(fname)
country = SCons.Util.splitext(file.name)[0]
if not languages or country in languages:
result = env.Transfiles(file)
# FIXME
def installCygwinLDScript(path): def installCygwinLDScript(path):