1 # vi:filetype=python:expandtab:tabstop=2:shiftwidth=2
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
9 # Full author contact details are available in file CREDITS.
12 # This is a scons based building system for lyx, you can use it as follows:
14 # $ cd development/scons
15 # $ scons [options] [targets]
17 # $ scons -f development/scons/SConstruct [options] [targets]
19 # $ scons [prefix=.] install
22 # * targets can be one or more of lyx, tex2lyx, client, po, install.
23 # default to lyx, you can use 'scons all' to build all targets except
25 # * options: use scons -h for details about options, the most important
26 # one is frontend=qt3|qt4.
27 # - qt3 is used by default on linux, cygwin and mac
28 # - qt4 is used by default on win32/mingw
30 # File layouts (Important):
31 # * Unless you specify builddir=dir, building will happen
32 # in $BUILDDIR = $mode, which can be debug or release
33 # * $BUILDDIR has subdirectories
34 # libs: all intermediate libraries
35 # boost: boost libraries, if boost=included is used
36 # qt3/4: frontend-specific objects
37 # * executables will be copied to $BUILDDIR/
40 # * scons fast_start=yes
41 # If env.cache exists, bypass all tests and use existing src/config.h
43 # * scons --config=force
44 # force re-configuration (use scons -H for details)
46 # * check config.log to see why config has failed
48 # * use extra_inc_path, extra_lib_path, qt_dir, qt_inc_path
49 # qt_lib_path to help locate qt and other libraries.
50 # There are also extra_inc_path1, extra_lib_path1 if you need to spacify
51 # more than one extra paths.
53 # * executed commands will be logged in scons_lyx.log. You can use logfile=
54 # option to save log to another file.
58 # * scons dist etc may be added later. Interested contributors can follow
59 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/AccumulateBuilder
61 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/DistTarBuilder
62 # Please also see the commented out code in scons_utils.py
64 # * NSIS support can be found here.
65 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/NsisSconsTool
68 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/RpmHonchoTemp
70 # However, I decide to wait since scons seems to be standardizing these
74 import os, sys, copy, cPickle
76 # config/scons_utils.py defines a few utility function
77 sys.path.append('config')
78 import scons_utils as utils
80 #----------------------------------------------------------
81 # Required runtime environment
82 #----------------------------------------------------------
84 # FIXME: I remember lyx requires higher version of python?
85 EnsurePythonVersion(1, 5)
86 # Please use at least 0.96.91 (not 0.96.1)
87 EnsureSConsVersion(0, 96)
89 # determine where I am ...
91 # called as 'scons -f development/scons/SConstruct'
92 if os.path.isfile('SConstruct'):
95 # called as 'cd development/scons; scons'
98 SCONS_DIR = 'development/scons'
100 #----------------------------------------------------------
102 #----------------------------------------------------------
104 # some global settings
105 PACKAGE_VERSION = '1.5.0svn'
107 default_build_mode = 'debug'
110 PACKAGE_BUGREPORT = 'lyx-devel@lists.lyx.org'
112 PACKAGE_TARNAME = 'lyx'
113 PACKAGE_STRING = '%s %s' % (PACKAGE_NAME, PACKAGE_VERSION)
116 # various cache/log files
117 default_log_file = 'scons_lyx.log'
118 env_cache_file = 'env.cache'
121 #----------------------------------------------------------
122 # platform dependent settings
123 #----------------------------------------------------------
125 platform_name = 'win32'
126 default_frontend = 'qt4'
127 # boost and gettext are unlikely to be installed already
128 default_boost_opt = 'included'
129 default_gettext_opt = 'included'
130 default_pch_opt = False
131 default_with_x = False
132 spell_checker = 'auto'
133 # boost_posix indicates to boost which API to use (posix or windows).
134 # If not specified, boost tries to figure out by itself, but it may fail.
136 packaging_method = 'windows'
137 default_prefix = 'c:/program files/lyx'
138 share_dir = 'Resources'
139 man_dir = 'Resources/man/man1'
140 locale_dir = 'Resources/locale'
141 elif os.name == 'posix' and sys.platform != 'cygwin':
142 platform_name = sys.platform
143 default_frontend = 'qt3'
144 # try to use system boost/gettext libraries
145 default_boost_opt = 'auto'
146 default_gettext_opt = 'auto'
147 default_pch_opt = False
148 default_with_x = True
150 packaging_method = 'posix'
151 default_prefix = '/usr/local/'
152 share_dir = 'share/lyx'
154 locale_dir = 'share/locale'
155 elif os.name == 'posix' and sys.platform == 'cygwin':
156 platform_name = 'cygwin'
157 default_frontend = 'qt3'
158 # force the use of cygwin/boost/gettext
159 default_boost_opt = 'system'
160 default_gettext_opt = 'system'
161 default_pch_opt = False
162 default_with_x = True
164 packaging_method = 'posix'
165 default_prefix = '/usr/local/'
166 share_dir = 'share/lyx'
168 locale_dir = 'share/locale'
169 elif os.name == 'darwin':
170 platform_name = 'mac'
171 default_frontend = 'qt3'
173 default_boost_opt = 'included'
174 default_gettext_opt = 'included'
175 default_pch_opt = False
176 default_with_x = False
178 packaging_method = 'mac'
179 # FIXME: where to install?
180 default_prefix = '/usr/local/'
181 share_dir = 'Resources'
182 man_dir = 'Resources/man/man1'
183 locale_dir = 'Resources/locale'
184 else: # unsupported system
185 platform_name = 'others'
186 default_frontend = 'qt3'
188 default_boost_opt = 'included'
189 default_gettext_opt = 'included'
190 default_pch_opt = False
191 default_with_x = True
193 packaging_method = 'posix'
194 default_prefix = '/usr/local/'
195 share_dir = 'share/lyx'
197 locale_dir = 'share/locale'
200 #---------------------------------------------------------
202 #----------------------------------------------------------
204 if os.path.isfile('config.py'):
205 print "Getting options from config.py..."
206 print open('config.py').read()
208 opts = Options(['config.py'])
211 EnumOption('frontend', 'Main GUI', default_frontend,
212 allowed_values = ('xform', 'qt3', 'qt4', 'gtk') ),
213 # debug or release build
214 EnumOption('mode', 'Building method', default_build_mode,
215 allowed_values = ('debug', 'release') ),
218 'Use included, system boost library, or try sytem boost first.',
221 'auto', # detect boost, if not found, use included
222 'included', # always use included boost
223 'system', # always use system boost, fail if can not find
225 # FIXME: not implemented yet.
226 EnumOption('gettext',
227 'Use included, system gettext library, or try sytem gettext first',
230 'auto', # detect gettext, if not found, use included
231 'included', # always use included gettext
232 'system', # always use system gettext, fail if can not find
235 EnumOption('spell', 'Choose spell checker to use.', 'auto',
236 allowed_values = ('aspell', 'pspell', 'ispell', 'auto') ),
238 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
239 # FIXME: I do not know how pch is working. Ignore this option now.
240 BoolOption('pch', '(NA) Whether or not use pch', default_pch_opt),
241 # FIXME: Not implemented yet.
242 BoolOption('version_suffix', '(NA) Whether or not add version suffix', False),
243 # enable assertion, (config.h has ENABLE_ASSERTIOS
244 BoolOption('assertions', 'Use assertions', True),
245 # enable warning, (config.h has WITH_WARNINGS)
246 BoolOption('warnings', 'Use warnings', True),
247 # enable glib, (config.h has _GLIBCXX_CONCEPT_CHECKS)
248 BoolOption('concept_checks', 'Enable concept checks', True),
249 # FIXME: I do not know what is nls
250 BoolOption('nls', '(NA) Whether or not use native language support', False),
251 # FIXME: not implemented
252 BoolOption('profile', '(NA) Whether or not enable profiling', False),
253 # FIXME: not implemented
254 BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False),
256 BoolOption('X11', 'Use x11 windows system', default_with_x),
257 # FIXME: not implemented
258 BoolOption('libintl', '(NA) Use libintl library', False),
260 PathOption('qt_dir', 'Path to qt directory', None),
262 PathOption('qt_include_path', 'Path to qt include directory', None),
264 PathOption('qt_lib_path', 'Path to qt library directory', None),
265 # build directory, will use $mode if not set
266 PathOption('build_dir', 'Build directory', None),
267 # extra include and libpath
268 PathOption('extra_inc_path', 'Extra include path', None),
270 PathOption('extra_lib_path', 'Extra library path', None),
272 PathOption('extra_inc_path1', 'Extra include path', None),
274 PathOption('extra_lib_path1', 'Extra library path', None),
275 # can be set to a non-existing directory
276 ('prefix', 'install architecture-independent files in PREFIX', None),
278 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
279 # FIXME: not implemented
280 PathOption('intl_prefix', '(NA) Path to intl library', None),
282 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
284 PathOption('aikasurus_path', 'Path to aikasurus library', None),
285 # environment variable can be set as options. (DO NOT set defaults)
287 ('LINK', '$LINK', None),
288 ('CPP', '$CPP', None),
289 ('CXX', '$CXX', None),
290 ('CXXCPP', '$CXXCPP', None),
291 ('CCFLAGS', '$CCFLAGS', None),
292 ('CPPFLAGS', '$CPPFLAGS', None),
293 ('LDFLAGS', '$LDFLAGS', None),
297 #---------------------------------------------------------
298 # Setting up environment
299 #---------------------------------------------------------
301 env = Environment(options = opts)
303 # Determine the frontend to use, which may be loaded
305 frontend = env.get('frontend', default_frontend)
306 # make sure the key exists
307 env['frontend'] = frontend
309 use_X11 = env.get('X11', default_with_x)
311 # whether or not use current config.h, and cached tests
312 if env['fast_start'] and os.path.isfile(env_cache_file):
314 SetOption('implicit_cache', 1)
315 cache_file = open(env_cache_file)
316 env_cache = cPickle.load(cache_file)
318 print '------------ fast_start mode --------------------'
319 print ' Use cached test results and current config.h'
320 print ' use fast_start=no to override'
321 print '-------------------------------------------------'
324 SetOption('implicit_cache', 0)
327 # set individual variables since I do not really like ENV = os.environ
328 env['ENV']['PATH'] = os.environ.get('PATH')
329 env['ENV']['HOME'] = os.environ.get('HOME')
330 env['TOP_SRC_DIR'] = TOP_SRC_DIR
331 env['SCONS_DIR'] = SCONS_DIR
332 # install to default_prefix by default
333 env['PREFIX'] = env.get('prefix', default_prefix)
334 if env.has_key('exec_prefix'):
335 env['BIN_DIR'] = env['exec_prefix']
337 env['BIN_DIR'] = os.path.join(env['PREFIX'], 'bin')
338 env['SHARE_DIR'] = os.path.join(env['PREFIX'], share_dir)
339 env['MAN_DIR'] = os.path.join(env['PREFIX'], man_dir)
340 env['LOCALE_DIR'] = os.path.join(env['PREFIX'], locale_dir)
342 # speed up source file processing
343 #env['CPPSUFFIXES'] = ['.C', '.cc', '.cpp']
344 #env['CXXSUFFIX'] = ['.C']
346 def getEnvVariable(env, name):
347 # first try command line argument (override environment settings)
348 if ARGUMENTS.has_key(name) and ARGUMENTS[name].strip() != '':
349 env[name] = ARGUMENTS[name]
350 # then use environment default
351 elif os.environ.has_key(name) and os.environ[name].strip() != '':
352 env[name] = os.environ[name]
353 print "Acquiring varaible %s from system environment: %s" % (name, env[name])
354 # finally, env['CC'] etc is set to the default values of Options.
355 # and env['CPP'] etc does not exist
357 getEnvVariable(env, 'CC')
358 getEnvVariable(env, 'LINK')
359 getEnvVariable(env, 'CPP')
360 getEnvVariable(env, 'CXX')
361 getEnvVariable(env, 'CXXCPP')
362 getEnvVariable(env, 'CCFLAGS')
363 getEnvVariable(env, 'CXXFLAGS')
364 getEnvVariable(env, 'CPPFLAGS')
365 getEnvVariable(env, 'LDFLAGS')
369 # frontend, mode, BUILDDIR and LOCALLIBPATH=BUILDDIR/libs
371 env['mode'] = env.get('mode', default_build_mode)
372 # lyx will be built to $build/build_dir so it is possible
373 # to build multiple build_dirs using the same source
374 # $mode can be debug or release
375 if env.has_key('build_dir') and env['build_dir']:
376 build_dir = env['build_dir']
377 env['BUILDDIR'] = build_dir
379 # Determine the name of the build $mode
380 env['BUILDDIR'] = '#' + env['mode']
381 # all built libraries will go to build_dir/libs
382 # (This is different from the make file approach)
383 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
384 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
387 # QTDIR, QT_LIB_PATH, QT_INC_PATH
389 if env.has_key('qt_dir') and env['qt_dir']:
390 env['QTDIR'] = env['qt_dir']
391 # add path to the qt tools
392 env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
393 # set environment so that moc etc can be found even if its path is not set properly
394 env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
396 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
398 if env.has_key('qt_lib_path') and env['qt_lib_path']:
399 env['QT_LIB_PATH'] = env['qt_lib_path']
401 env['QT_LIB_PATH'] = '$QTDIR/lib'
402 env.AppendUnique(LIBPATH = ['$QT_LIB_PATH'])
403 # qt4 seems to be using pkg_config
404 env.PrependENVPath('PKG_CONFIG_PATH', env.subst('$QT_LIB_PATH'))
406 if env.has_key('qt_inc_path') and env['qt_inc_path']:
407 env['QT_INC_PATH'] = env['qt_inc_path']
408 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
409 env['QT_INC_PATH'] = '$QTDIR/include'
410 else: # have to guess
411 env['QT_INC_PATH'] = '/usr/include/$frontend/'
412 # Note that this CPPPATH is for testing only
413 # it will be removed before calling SConscript
414 env.AppendUnique(CPPPATH = env['QT_INC_PATH'])
417 # extra_inc_path and extra_lib_path
419 if env.has_key('extra_inc_path') and env['extra_inc_path']:
420 env.AppendUnique(CPPPATH = [env['extra_inc_path']])
421 if env.has_key('extra_lib_path') and env['extra_lib_path']:
422 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
423 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
424 env.AppendUnique(CPPPATH = [env['extra_inc_path1']])
425 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
426 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
427 if env.has_key('aikasurus_path') and env['aikasurus_path']:
428 env.AppendUnique(LIBPATH = [env['aikasurus_path']])
431 # this is a bit out of place (after auto-configration)
432 # but it is required to do the tests.
433 if platform_name == 'win32':
434 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
437 # under windows, scons is confused by .C/.c and uses gcc instead of
438 # g++. I am forcing the use of g++ here. This is expected to change
439 # after lyx renames all .C files to .cpp
441 # Note that this step has to be after env.Tool('mingw') step
442 # since env.Tool('mingw') will set env['CC'] etc.
444 if env.has_key('CXX') and env['CXX']:
445 env['CC'] = env['CXX']
446 env['LINK'] = env['CXX']
452 #----------------------------------------------------------
454 #----------------------------------------------------------
456 conf = Configure(env,
458 'CheckPkgConfig' : utils.checkPkgConfig,
459 'CheckPackage' : utils.checkPackage,
460 'CheckPutenv' : utils.checkPutenv,
461 'CheckIstreambufIterator' : utils.checkIstreambufIterator,
462 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
463 'CheckStdCount' : utils.checkStdCount,
464 'CheckSelectArgType' : utils.checkSelectArgType,
465 'CheckBoostLibraries' : utils.checkBoostLibraries,
466 'CheckMsgFmt' : utils.checkMsgFmt,
470 # pkg-config? (if not, we use hard-coded options)
472 if conf.CheckPkgConfig('0.15.0'):
473 env['HAS_PKG_CONFIG'] = True
475 print 'pkg-config >= 0.1.50 is not found'
476 env['HAS_PKG_CONFIG'] = False
477 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
479 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
481 # zlib? This is required. (fast_start assumes the existance of zlib)
482 if not fast_start and not conf.CheckLibWithHeader('z', 'zlib.h', 'C'):
483 print 'Did not find libz or zlib.h, exiting!'
489 # qt3 does not use pkg_config
490 if frontend == 'qt3':
491 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
492 print 'Did not find qt libraries, exiting!'
494 elif frontend == 'qt4':
496 # first: try pkg_config
497 if env['HAS_PKG_CONFIG']:
498 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
499 env['QT4_PKG_CONFIG'] = succ
500 # second: try to link to it
502 # FIXME: under linux, I can test the following perfectly
503 # However, under windows, lib names need to passed as libXXX4.a ...
504 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
505 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
506 # third: try to look up the path
509 for lib in ['QtCore', 'QtGui']:
510 # windows version has something like QtGui4 ...
511 if not (os.path.isfile(os.path.join(env.subst('$QT_LIB_PATH'), 'lib%s.a' % lib)) or \
512 os.path.isfile(os.path.join(env.subst('$QT_LIB_PATH'), 'lib%s4.a' % lib))):
515 # still can not find it
517 print "Qt4 libraries are found."
519 print 'Did not find qt libraries, exiting!'
525 env['SOCKET_LIBS'] = []
526 if conf.CheckLib('socket'):
527 env['SOCKET_LIBS'].append('socket')
529 # nsl is the network services library and provides a
530 # transport-level interface to networking services.
531 if conf.CheckLib('nsl'):
532 env['SOCKET_LIBS'].append('nsl')
534 env_cache['SOCKET_LIBS'] = env['SOCKET_LIBS']
536 env['SOCKET_LIBS'] = env_cache['SOCKET_LIBS']
539 # check boost libraries
540 boost_opt = ARGUMENTS.get('boost', default_boost_opt)
541 # check for system boost
543 if boost_opt in ['auto', 'system']:
544 pathes = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
545 sig = conf.CheckBoostLibraries('boost_signals', pathes)
546 reg = conf.CheckBoostLibraries('boost_regex', pathes)
547 fil = conf.CheckBoostLibraries('boost_filesystem', pathes)
548 ios = conf.CheckBoostLibraries('boost_iostreams', pathes)
549 # if any of them is not found
550 if ('' in [sig[0], reg[0], fil[0], ios[0]]):
551 if boost_opt == 'system':
552 print "Can not find system boost libraries"
553 print "Please supply a path through extra_lib_path and try again."
554 print "Or use boost=included to use included boost libraries."
557 env['BOOST_LIBRARIES'] = [sig[1], reg[1], fil[1], ios[1]]
558 # assume all boost libraries are in the same path...
559 env.AppendUnique(LIBPATH = [sig[0]])
560 env['INCLUDED_BOOST'] = False
562 # now, auto and succ = false, or boost=included
564 # we do not need to set LIBPATH now.
565 env['BOOST_LIBRARIES'] = ['boost_signals', 'boost_regex',
566 'boost_filesystem', 'boost_iostreams']
567 env['INCLUDED_BOOST'] = True
568 env_cache['BOOST_LIBRARIES'] = env['BOOST_LIBRARIES']
569 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
571 env['BOOST_LIBRARIES'] = env_cache['BOOST_LIBRARIES']
572 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
575 # check for msgfmt command
577 env['MSGFMT'] = conf.CheckMsgFmt()
578 env_cache['MSGFMT'] = env['MSGFMT']
580 env['MSGFMT'] = env_cache['MSGFMT']
583 #----------------------------------------------------------
584 # Generating config.h
585 #----------------------------------------------------------
587 print "Generating ", utils.config_h, "..."
589 # I do not handle all macros in src/config.h.in, rather I am following a list
590 # of *used-by-lyx* macros compiled by Abdelrazak Younes <younes.a@free.fr>
592 # Note: addToConfig etc are defined in scons_util
593 utils.startConfigH(TOP_SRC_DIR)
613 ('io.h', 'HAVE_IO_H', 'c'),
614 ('limits.h', 'HAVE_LIMITS_H', 'c'),
615 ('locale.h', 'HAVE_LOCALE_H', 'c'),
616 ('locale', 'HAVE_LOCALE', 'cxx'),
617 ('process.h', 'HAVE_PROCESS_H', 'c'),
618 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
619 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
620 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
621 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
622 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
623 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
624 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
625 ('utime.h', 'HAVE_UTIME_H', 'c'),
626 ('istream', 'HAVE_ISTREAM', 'cxx'),
627 ('ostream', 'HAVE_OSTREAM', 'cxx'),
628 ('ios', 'HAVE_IOS', 'cxx')
631 for header in headers:
632 if (header[2] == 'c' and conf.CheckCHeader(header[0])) or \
633 (header[2] == 'cxx' and conf.CheckCXXHeader(header[0])):
634 utils.addToConfig('#define %s 1' % header[1], TOP_SRC_DIR)
636 utils.addToConfig('/* #undef %s */' % header[1], TOP_SRC_DIR)
657 ('open', 'HAVE_OPEN'),
658 ('close', 'HAVE_CLOSE'),
659 ('popen', 'HAVE_POPEN'),
660 ('pclose', 'HAVE_PCLOSE'),
661 ('_open', 'HAVE__OPEN'),
662 ('_close', 'HAVE__CLOSE'),
663 ('_popen', 'HAVE__POPEN'),
664 ('_pclose', 'HAVE__PCLOSE'),
665 ('getpid', 'HAVE_GETPID'),
666 ('_getpid', 'HAVE__GETPID'),
667 ('mkdir', 'HAVE_MKDIR'),
668 ('_mkdir', 'HAVE__MKDIR'),
669 ('mktemp', 'HAVE_MKTEMP'),
670 ('mkstemp', 'HAVE_MKSTEMP'),
671 ('strerror', 'HAVE_STRERROR'),
672 ('fcntl', 'HAVE_FCNTL')
675 for func in functions:
676 if conf.CheckFunc(func[0]):
677 utils.addToConfig('#define %s 1' % func[1], TOP_SRC_DIR)
679 utils.addToConfig('/* #undef %s */' % func[1], TOP_SRC_DIR)
684 utils.addToConfig('#define PACKAGE "%s"' % PACKAGE, TOP_SRC_DIR)
685 utils.addToConfig('#define PACKAGE_VERSION "%s"' % PACKAGE_VERSION, TOP_SRC_DIR)
687 utils.addToConfig('#define DEVEL_VERSION 1', TOP_SRC_DIR)
692 # _GLIBCXX_CONCEPT_CHECKS
694 # items are (ENV, ARGUMENTS)
696 ('ENABLE_ASSERTIONS', 'assertions'),
697 ('ENABLE_NLS', 'nls'),
698 ('WITH_WARNINGS', 'warnings'),
699 ('_GLIBCXX_CONCEPT_CHECKS', 'concept_checks'),
703 if (env.has_key(val[0]) and env[val[0]]) or \
704 ARGUMENTS.get(val[1]):
705 utils.addToConfig('#define %s 1' % val[0], TOP_SRC_DIR)
707 utils.addToConfig('/* #undef %s */' % val[0], TOP_SRC_DIR)
710 env['EXTRA_LIBS'] = []
712 # AIKSAURUS_H_LOCATION
713 if conf.CheckLib('Aiksaurus'):
714 utils.addToConfig("#define HAVE_LIBAIKSAURUS 1", TOP_SRC_DIR)
715 if (conf.CheckCXXHeader("Aiksaurus.h")):
716 utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus.h>", TOP_SRC_DIR)
717 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
718 utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus/Aiksaurus.h>", TOP_SRC_DIR)
720 utils.addToConfig("#define AIKSAURUS_H_LOCATION", TOP_SRC_DIR)
721 env['EXTRA_LIBS'].append('Aiksaurus')
727 # determine headers to use
728 spell_engine = ARGUMENTS.get('spell', 'auto')
729 spell_detected = False
730 if spell_engine in ['auto', 'aspell'] and \
731 conf.CheckLib('aspell'):
732 utils.addToConfig('#define USE_ASPELL 1', TOP_SRC_DIR)
733 env['USE_ASPELL'] = True
734 env['USE_PSPELL'] = False
735 env['USE_ISPELL'] = False
736 env['EXTRA_LIBS'].append('aspell')
737 spell_detected = True
738 elif spell_engine in ['auto', 'pspell'] and \
739 conf.CheckLib('pspell'):
740 utils.addToConfig('#define USE_PSPELL 1', TOP_SRC_DIR)
741 env['USE_ASPELL'] = False
742 env['USE_PSPELL'] = True
743 env['USE_ISPELL'] = False
744 env['EXTRA_LIBS'].append('pspell')
745 spell_detected = True
746 elif spell_engine in ['auto', 'ispell'] and \
747 conf.CheckLib('ispell'):
748 utils.addToConfig('#define USE_ISPELL 1', TOP_SRC_DIR)
749 env['USE_ASPELL'] = False
750 env['USE_PSPELL'] = False
751 env['USE_ISPELL'] = True
752 env['EXTRA_LIBS'].append('ispell')
753 spell_detected = True
755 if not spell_detected:
756 env['USE_ASPELL'] = False
757 env['USE_PSPELL'] = False
758 env['USE_ISPELL'] = False
759 # FIXME: can lyx work without an spell engine
760 if spell_engine == 'auto':
761 print "Warning: Can not locate any spell checker"
763 print "Warning: Can not locate specified spell checker:", spell_engine
765 # env['EXTRA_LIBS'] will be modified later, so a unique copy is needed
766 # NOTE that we do *not* save qt_libs in environment.
767 env_cache['EXTRA_LIBS'] = copy.copy(env['EXTRA_LIBS'])
768 env_cache['USE_ASPELL'] = env['USE_ASPELL']
769 env_cache['USE_PSPELL'] = env['USE_PSPELL']
770 env_cache['USE_ISPELL'] = env['USE_ISPELL']
772 # USE_POSIX_PACKAGING
773 # USE_MACOSX_PACKAGING
774 # USE_WINDOWS_PACKAGING
775 if packaging_method == 'windows':
776 utils.addToConfig('#define USE_WINDOWS_PACKAGING 1', TOP_SRC_DIR)
777 elif packaging_method == 'posix':
778 utils.addToConfig('#define USE_POSIX_PACKAGING 1', TOP_SRC_DIR)
779 elif packaging_method == 'mac':
780 utils.addToConfig('#define USE_MACOSX_PACKAGING 1', TOP_SRC_DIR)
784 utils.addToConfig('#define BOOST_POSIX 1', TOP_SRC_DIR)
786 utils.addToConfig('/* #undef BOOST_POSIX */', TOP_SRC_DIR)
789 if conf.CheckPutenv():
790 utils.addToConfig('#define HAVE_PUTENV 1', TOP_SRC_DIR)
792 utils.addToConfig('/* #undef HAVE_PUTENV */', TOP_SRC_DIR)
794 # HAVE_DECL_ISTREAMBUF_ITERATOR
795 if conf.CheckIstreambufIterator():
796 utils.addToConfig('#define HAVE_DECL_ISTREAMBUF_ITERATOR 1', TOP_SRC_DIR)
798 utils.addToConfig('/* #undef HAVE_DECL_ISTREAMBUF_ITERATOR */', TOP_SRC_DIR)
800 # MKDIR_TAKES_ONE_ARG
801 if conf.CheckMkdirOneArg():
802 utils.addToConfig('#define MKDIR_TAKES_ONE_ARG 1', TOP_SRC_DIR)
804 utils.addToConfig('/* #undef MKDIR_TAKES_ONE_ARG */', TOP_SRC_DIR)
807 if conf.CheckStdCount():
808 utils.addToConfig('#define HAVE_STD_COUNT 1', TOP_SRC_DIR)
810 utils.addToConfig('/* #undef HAVE_STD_COUNT */', TOP_SRC_DIR)
815 (arg1, arg234, arg5) = conf.CheckSelectArgType()
816 utils.addToConfig('#define SELECT_TYPE_ARG1 %s' % arg1, TOP_SRC_DIR)
817 utils.addToConfig('#define SELECT_TYPE_ARG234 %s' % arg234, TOP_SRC_DIR)
818 utils.addToConfig('#define SELECT_TYPE_ARG5 %s' % arg5, TOP_SRC_DIR)
822 # WANT_GETFILEATTRIBUTESEX_WRAPPER
823 utils.endConfigH(TOP_SRC_DIR)
826 # only a few variables need to be rescanned
827 env['EXTRA_LIBS'] = copy.copy(env_cache['EXTRA_LIBS'])
828 env['USE_ASPELL'] = env_cache['USE_ASPELL']
829 env['USE_PSPELL'] = env_cache['USE_PSPELL']
830 env['USE_ISPELL'] = env_cache['USE_ISPELL']
833 # Finish auto-configuration
836 #----------------------------------------------------------
837 # Now set up our build process accordingly
838 #----------------------------------------------------------
841 # QT_LIB etc (EXTRA_LIBS holds lib for each frontend)
843 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
844 # in their respective directory and specialized env.
846 if frontend == 'qt3':
847 # note: env.Tool('qt') my set QT_LIB to qt
848 env['QT_LIB'] = 'qt-mt'
849 env['EXTRA_LIBS'].append('qt-mt')
850 if platform_name == 'cygwin' and use_X11:
851 env['EXTRA_LIBS'].extend(['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
852 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
854 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
855 elif frontend == 'qt4':
856 if platform_name == "win32":
857 env['QT_LIB'] = ['QtCore4', 'QtGui4']
859 env['QT_LIB'] = ['QtCore', 'QtGui']
860 env['EXTRA_LIBS'] += env['QT_LIB']
862 print "Can not locate qt tools"
863 print "What I get is "
864 print " QTDIR: ", env['QTDIR']
867 if platform_name in ['win32', 'cygwin']:
868 # the final link step needs stdc++ to succeed under mingw
869 # FIXME: shouldn't g++ automatically link to stdc++?
870 env['SYSTEM_LIBS'] = ['shlwapi', 'z', 'stdc++']
872 env['SYSTEM_LIBS'] = ['z']
875 # Build parameters CPPPATH etc
877 # boost is always in, src is needed for config.h
879 # Note that previously added QT_DIR/include etc is removed
880 # they will be added when processing for example src/qt3
881 env['CPPPATH'] = ['$TOP_SRC_DIR/boost', '$TOP_SRC_DIR/src']
883 # TODO: add (more) appropriate compiling options (-DNDEBUG etc)
884 # for debug/release mode
885 if ARGUMENTS.get('mode', default_build_mode) == 'debug':
886 env.AppendUnique(CCFLAGS = [])
888 env.AppendUnique(CCFLAGS = [])
891 # Customized builders
893 # install customized builders
894 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
895 # FIXME: there must be a better way.
896 env['BUILDERS']['fileCopy'] = Builder(action = utils.env_filecopy)
899 # A Link script for cygwin see
900 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
901 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
904 if platform_name == 'cygwin':
905 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
906 ld_script = utils.installCygwinLDScript(ld_script_path)
907 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
908 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
913 # src/support/package.C.in needs the following to replace
914 # LYX_ABS_INSTALLED_DATADIR (e.g. /usr/local/lyx/share/lyx)
915 env['LYX_DIR'] = env['SHARE_DIR']
916 # LYX_ABS_INSTALLED_LOCALEDIR
917 env['LOCALEDIR'] = env['LOCALE_DIR']
918 env['TOP_SRCDIR'] = env['TOP_SRC_DIR']
919 env['PROGRAM_SUFFIX'] = PROGRAM_SUFFIX
920 # needed by src/version.C.in => src/version.C
921 env['PACKAGE_VERSION'] = PACKAGE_VERSION
922 # fill in the version info
923 env['VERSION_INFO'] = '''Configuration
925 Special build flags: %s
927 C Compiler flags: %s %s
929 C++ Compiler LyX flags: %s
930 C++ Compiler flags: %s %s
932 Linker user flags: %s
934 Builing directory: %s
935 Local library directory: %s
943 LyX binary dir: FIXME
945 ''' % (platform_name,
946 env.subst('$CCFLAGS'), env.subst('$CC'),
947 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
948 env.subst('$CXX'), env.subst('$CXXFLAGS'),
949 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
950 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
951 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
952 str(env['LIBPATH']), str(env['BOOST_LIBRARIES']),
953 str(env['EXTRA_LIBS']), str(env['SYSTEM_LIBS']),
954 env['frontend'], packaging_method)
956 if env['frontend'] in ['qt3', 'qt4']:
957 env['VERSION_INFO'] += ''' include dir: %s
960 ''' % (env.subst('$QT_INC_PATH'), env.subst('$QT_LIB_PATH'), use_X11)
963 print env['VERSION_INFO']
966 # Mingw command line may be too short for our link usage,
967 # Here we use a trick from scons wiki
968 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
970 # I also would like to add logging (commands only) capacity to the
972 logfile = env.get('logfile', default_log_file)
973 if logfile != '' or platform_name == 'win32':
975 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
976 info = '''# This is a log of commands used by scons to build lyx
980 ''' % (time.asctime(), ' '.join(sys.argv),
981 env['VERSION_INFO'].replace('\n','\n# ')) )
987 # -h will print out help info
988 Help(opts.GenerateHelpText(env))
989 # save environment settings (for fast_start option)
990 cache_file = open(env_cache_file, 'w')
991 cPickle.dump(env_cache, cache_file)
994 #----------------------------------------------------------
996 #----------------------------------------------------------
999 # this has been the source of problem on some platforms...
1000 # needs more testing
1001 env.SConsignFile('%s/.sconsign' % env['BUILDDIR'][1:])
1002 # this usage needs further investigation.
1003 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1005 env['BUILD_TARGETS'] = BUILD_TARGETS
1007 print "Building all targets recursively"
1009 env.SConscript('$SCONS_DIR/SConscript', duplicate = 0)