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['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')
528 env['HAS_SOCKET_LIB'] = True
530 env['HAS_SOCKET_LIB'] = False
532 # nsl is the network services library and provides a
533 # transport-level interface to networking services.
534 if conf.CheckLib('nsl'):
535 env['SOCKET_LIBS'].append('nsl')
537 env_cache['SOCKET_LIBS'] = env['SOCKET_LIBS']
538 env_cache['HAS_SOCKET_LIB'] = env['HAS_SOCKET_LIB']
540 env['SOCKET_LIBS'] = env_cache['SOCKET_LIBS']
541 env['HAS_SOCKET_LIB'] = env_cache['HAS_SOCKET_LIB']
544 # check boost libraries
545 boost_opt = ARGUMENTS.get('boost', default_boost_opt)
546 # check for system boost
548 if boost_opt in ['auto', 'system']:
549 pathes = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
550 sig = conf.CheckBoostLibraries('boost_signals', pathes)
551 reg = conf.CheckBoostLibraries('boost_regex', pathes)
552 fil = conf.CheckBoostLibraries('boost_filesystem', pathes)
553 ios = conf.CheckBoostLibraries('boost_iostreams', pathes)
554 # if any of them is not found
555 if ('' in [sig[0], reg[0], fil[0], ios[0]]):
556 if boost_opt == 'system':
557 print "Can not find system boost libraries"
558 print "Please supply a path through extra_lib_path and try again."
559 print "Or use boost=included to use included boost libraries."
562 env['BOOST_LIBRARIES'] = [sig[1], reg[1], fil[1], ios[1]]
563 # assume all boost libraries are in the same path...
564 env.AppendUnique(LIBPATH = [sig[0]])
565 env['INCLUDED_BOOST'] = False
567 # now, auto and succ = false, or boost=included
569 # we do not need to set LIBPATH now.
570 env['BOOST_LIBRARIES'] = ['boost_signals', 'boost_regex',
571 'boost_filesystem', 'boost_iostreams']
572 env['INCLUDED_BOOST'] = True
573 env_cache['BOOST_LIBRARIES'] = env['BOOST_LIBRARIES']
574 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
576 env['BOOST_LIBRARIES'] = env_cache['BOOST_LIBRARIES']
577 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
580 # check for msgfmt command
582 env['MSGFMT'] = conf.CheckMsgFmt()
583 env_cache['MSGFMT'] = env['MSGFMT']
585 env['MSGFMT'] = env_cache['MSGFMT']
588 #----------------------------------------------------------
589 # Generating config.h
590 #----------------------------------------------------------
592 print "Generating ", utils.config_h, "..."
594 # I do not handle all macros in src/config.h.in, rather I am following a list
595 # of *used-by-lyx* macros compiled by Abdelrazak Younes <younes.a@free.fr>
597 # Note: addToConfig etc are defined in scons_util
598 utils.startConfigH(TOP_SRC_DIR)
618 ('io.h', 'HAVE_IO_H', 'c'),
619 ('limits.h', 'HAVE_LIMITS_H', 'c'),
620 ('locale.h', 'HAVE_LOCALE_H', 'c'),
621 ('locale', 'HAVE_LOCALE', 'cxx'),
622 ('process.h', 'HAVE_PROCESS_H', 'c'),
623 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
624 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
625 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
626 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
627 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
628 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
629 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
630 ('utime.h', 'HAVE_UTIME_H', 'c'),
631 ('istream', 'HAVE_ISTREAM', 'cxx'),
632 ('ostream', 'HAVE_OSTREAM', 'cxx'),
633 ('ios', 'HAVE_IOS', 'cxx')
636 for header in headers:
637 if (header[2] == 'c' and conf.CheckCHeader(header[0])) or \
638 (header[2] == 'cxx' and conf.CheckCXXHeader(header[0])):
639 utils.addToConfig('#define %s 1' % header[1], TOP_SRC_DIR)
641 utils.addToConfig('/* #undef %s */' % header[1], TOP_SRC_DIR)
662 ('open', 'HAVE_OPEN'),
663 ('close', 'HAVE_CLOSE'),
664 ('popen', 'HAVE_POPEN'),
665 ('pclose', 'HAVE_PCLOSE'),
666 ('_open', 'HAVE__OPEN'),
667 ('_close', 'HAVE__CLOSE'),
668 ('_popen', 'HAVE__POPEN'),
669 ('_pclose', 'HAVE__PCLOSE'),
670 ('getpid', 'HAVE_GETPID'),
671 ('_getpid', 'HAVE__GETPID'),
672 ('mkdir', 'HAVE_MKDIR'),
673 ('_mkdir', 'HAVE__MKDIR'),
674 ('mktemp', 'HAVE_MKTEMP'),
675 ('mkstemp', 'HAVE_MKSTEMP'),
676 ('strerror', 'HAVE_STRERROR'),
677 ('fcntl', 'HAVE_FCNTL')
680 for func in functions:
681 if conf.CheckFunc(func[0]):
682 utils.addToConfig('#define %s 1' % func[1], TOP_SRC_DIR)
684 utils.addToConfig('/* #undef %s */' % func[1], TOP_SRC_DIR)
689 utils.addToConfig('#define PACKAGE "%s"' % PACKAGE, TOP_SRC_DIR)
690 utils.addToConfig('#define PACKAGE_VERSION "%s"' % PACKAGE_VERSION, TOP_SRC_DIR)
692 utils.addToConfig('#define DEVEL_VERSION 1', TOP_SRC_DIR)
697 # _GLIBCXX_CONCEPT_CHECKS
699 # items are (ENV, ARGUMENTS)
701 ('ENABLE_ASSERTIONS', 'assertions'),
702 ('ENABLE_NLS', 'nls'),
703 ('WITH_WARNINGS', 'warnings'),
704 ('_GLIBCXX_CONCEPT_CHECKS', 'concept_checks'),
708 if (env.has_key(val[0]) and env[val[0]]) or \
709 ARGUMENTS.get(val[1]):
710 utils.addToConfig('#define %s 1' % val[0], TOP_SRC_DIR)
712 utils.addToConfig('/* #undef %s */' % val[0], TOP_SRC_DIR)
715 env['EXTRA_LIBS'] = []
717 # AIKSAURUS_H_LOCATION
718 if conf.CheckLib('Aiksaurus'):
719 utils.addToConfig("#define HAVE_LIBAIKSAURUS 1", TOP_SRC_DIR)
720 if (conf.CheckCXXHeader("Aiksaurus.h")):
721 utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus.h>", TOP_SRC_DIR)
722 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
723 utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus/Aiksaurus.h>", TOP_SRC_DIR)
725 utils.addToConfig("#define AIKSAURUS_H_LOCATION", TOP_SRC_DIR)
726 env['EXTRA_LIBS'].append('Aiksaurus')
732 # determine headers to use
733 spell_engine = ARGUMENTS.get('spell', 'auto')
734 spell_detected = False
735 if spell_engine in ['auto', 'aspell'] and \
736 conf.CheckLib('aspell'):
737 utils.addToConfig('#define USE_ASPELL 1', TOP_SRC_DIR)
738 env['USE_ASPELL'] = True
739 env['USE_PSPELL'] = False
740 env['USE_ISPELL'] = False
741 env['EXTRA_LIBS'].append('aspell')
742 spell_detected = True
743 elif spell_engine in ['auto', 'pspell'] and \
744 conf.CheckLib('pspell'):
745 utils.addToConfig('#define USE_PSPELL 1', TOP_SRC_DIR)
746 env['USE_ASPELL'] = False
747 env['USE_PSPELL'] = True
748 env['USE_ISPELL'] = False
749 env['EXTRA_LIBS'].append('pspell')
750 spell_detected = True
751 elif spell_engine in ['auto', 'ispell'] and \
752 conf.CheckLib('ispell'):
753 utils.addToConfig('#define USE_ISPELL 1', TOP_SRC_DIR)
754 env['USE_ASPELL'] = False
755 env['USE_PSPELL'] = False
756 env['USE_ISPELL'] = True
757 env['EXTRA_LIBS'].append('ispell')
758 spell_detected = True
760 if not spell_detected:
761 env['USE_ASPELL'] = False
762 env['USE_PSPELL'] = False
763 env['USE_ISPELL'] = False
764 # FIXME: can lyx work without an spell engine
765 if spell_engine == 'auto':
766 print "Warning: Can not locate any spell checker"
768 print "Warning: Can not locate specified spell checker:", spell_engine
770 # USE_POSIX_PACKAGING
771 # USE_MACOSX_PACKAGING
772 # USE_WINDOWS_PACKAGING
773 if packaging_method == 'windows':
774 utils.addToConfig('#define USE_WINDOWS_PACKAGING 1', TOP_SRC_DIR)
775 elif packaging_method == 'posix':
776 utils.addToConfig('#define USE_POSIX_PACKAGING 1', TOP_SRC_DIR)
777 elif packaging_method == 'mac':
778 utils.addToConfig('#define USE_MACOSX_PACKAGING 1', TOP_SRC_DIR)
782 utils.addToConfig('#define BOOST_POSIX 1', TOP_SRC_DIR)
784 utils.addToConfig('/* #undef BOOST_POSIX */', TOP_SRC_DIR)
787 if conf.CheckPutenv():
788 utils.addToConfig('#define HAVE_PUTENV 1', TOP_SRC_DIR)
790 utils.addToConfig('/* #undef HAVE_PUTENV */', TOP_SRC_DIR)
792 # HAVE_DECL_ISTREAMBUF_ITERATOR
793 if conf.CheckIstreambufIterator():
794 utils.addToConfig('#define HAVE_DECL_ISTREAMBUF_ITERATOR 1', TOP_SRC_DIR)
796 utils.addToConfig('/* #undef HAVE_DECL_ISTREAMBUF_ITERATOR */', TOP_SRC_DIR)
798 # MKDIR_TAKES_ONE_ARG
799 if conf.CheckMkdirOneArg():
800 utils.addToConfig('#define MKDIR_TAKES_ONE_ARG 1', TOP_SRC_DIR)
802 utils.addToConfig('/* #undef MKDIR_TAKES_ONE_ARG */', TOP_SRC_DIR)
805 if conf.CheckStdCount():
806 utils.addToConfig('#define HAVE_STD_COUNT 1', TOP_SRC_DIR)
808 utils.addToConfig('/* #undef HAVE_STD_COUNT */', TOP_SRC_DIR)
813 (arg1, arg234, arg5) = conf.CheckSelectArgType()
814 utils.addToConfig('#define SELECT_TYPE_ARG1 %s' % arg1, TOP_SRC_DIR)
815 utils.addToConfig('#define SELECT_TYPE_ARG234 %s' % arg234, TOP_SRC_DIR)
816 utils.addToConfig('#define SELECT_TYPE_ARG5 %s' % arg5, TOP_SRC_DIR)
820 # WANT_GETFILEATTRIBUTESEX_WRAPPER
821 utils.endConfigH(TOP_SRC_DIR)
823 # env['EXTRA_LIBS'] will be modified later, so a unique copy is needed
824 # NOTE that we do *not* save qt_libs in environment.
825 env_cache['EXTRA_LIBS'] = copy.copy(env['EXTRA_LIBS'])
826 env_cache['USE_ASPELL'] = env['USE_ASPELL']
827 env_cache['USE_PSPELL'] = env['USE_PSPELL']
828 env_cache['USE_ISPELL'] = env['USE_ISPELL']
831 # only a few variables need to be rescanned
832 env['EXTRA_LIBS'] = copy.copy(env_cache['EXTRA_LIBS'])
833 env['USE_ASPELL'] = env_cache['USE_ASPELL']
834 env['USE_PSPELL'] = env_cache['USE_PSPELL']
835 env['USE_ISPELL'] = env_cache['USE_ISPELL']
838 # Finish auto-configuration
841 #----------------------------------------------------------
842 # Now set up our build process accordingly
843 #----------------------------------------------------------
846 # QT_LIB etc (EXTRA_LIBS holds lib for each frontend)
848 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
849 # in their respective directory and specialized env.
851 if frontend == 'qt3':
852 # note: env.Tool('qt') my set QT_LIB to qt
853 env['QT_LIB'] = 'qt-mt'
854 env['EXTRA_LIBS'].append('qt-mt')
855 if platform_name == 'cygwin' and use_X11:
856 env['EXTRA_LIBS'].extend(['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
857 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
859 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
860 elif frontend == 'qt4':
861 if platform_name == "win32":
862 env['QT_LIB'] = ['QtCore4', 'QtGui4']
864 env['QT_LIB'] = ['QtCore', 'QtGui']
865 env['EXTRA_LIBS'] += env['QT_LIB']
867 print "Can not locate qt tools"
868 print "What I get is "
869 print " QTDIR: ", env['QTDIR']
872 if platform_name in ['win32', 'cygwin']:
873 # the final link step needs stdc++ to succeed under mingw
874 # FIXME: shouldn't g++ automatically link to stdc++?
875 env['SYSTEM_LIBS'] = ['shlwapi', 'z', 'stdc++']
877 env['SYSTEM_LIBS'] = ['z']
880 # Build parameters CPPPATH etc
882 # boost is always in, src is needed for config.h
884 # QT_INC_PATH is not needed for *every* source file
885 env['CPPPATH'].remove(env['QT_INC_PATH'])
886 env['CPPPATH'] += ['$TOP_SRC_DIR/boost', '$TOP_SRC_DIR/src']
888 # TODO: add (more) appropriate compiling options (-DNDEBUG etc)
889 # for debug/release mode
890 if ARGUMENTS.get('mode', default_build_mode) == 'debug':
891 env.AppendUnique(CCFLAGS = [])
893 env.AppendUnique(CCFLAGS = [])
896 # Customized builders
898 # install customized builders
899 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
900 # FIXME: there must be a better way.
901 env['BUILDERS']['fileCopy'] = Builder(action = utils.env_filecopy)
904 # A Link script for cygwin see
905 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
906 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
909 if platform_name == 'cygwin':
910 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
911 ld_script = utils.installCygwinLDScript(ld_script_path)
912 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
913 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
918 # src/support/package.C.in needs the following to replace
919 # LYX_ABS_INSTALLED_DATADIR (e.g. /usr/local/lyx/share/lyx)
920 env['LYX_DIR'] = env['SHARE_DIR']
921 # LYX_ABS_INSTALLED_LOCALEDIR
922 env['LOCALEDIR'] = env['LOCALE_DIR']
923 env['TOP_SRCDIR'] = env['TOP_SRC_DIR']
924 env['PROGRAM_SUFFIX'] = PROGRAM_SUFFIX
925 # needed by src/version.C.in => src/version.C
926 env['PACKAGE_VERSION'] = PACKAGE_VERSION
927 # fill in the version info
928 env['VERSION_INFO'] = '''Configuration
930 Special build flags: %s
932 C Compiler flags: %s %s
934 C++ Compiler LyX flags: %s
935 C++ Compiler flags: %s %s
937 Linker user flags: %s
939 Builing directory: %s
940 Local library directory: %s
945 include search path: %s
952 ''' % (platform_name,
953 env.subst('$CCFLAGS'), env.subst('$CC'),
954 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
955 env.subst('$CXX'), env.subst('$CXXFLAGS'),
956 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
957 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
958 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
959 str(env['LIBPATH']), str(env['BOOST_LIBRARIES']),
960 str(env['EXTRA_LIBS']), str(env['SYSTEM_LIBS']), str(env['CPPPATH']),
961 env['frontend'], packaging_method,
962 env['PREFIX'], env['BIN_DIR'], env['SHARE_DIR'])
964 if env['frontend'] in ['qt3', 'qt4']:
965 env['VERSION_INFO'] += ''' include dir: %s
968 ''' % (env.subst('$QT_INC_PATH'), env.subst('$QT_LIB_PATH'), use_X11)
971 print env['VERSION_INFO']
974 # Mingw command line may be too short for our link usage,
975 # Here we use a trick from scons wiki
976 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
978 # I also would like to add logging (commands only) capacity to the
980 logfile = env.get('logfile', default_log_file)
981 if logfile != '' or platform_name == 'win32':
983 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
984 info = '''# This is a log of commands used by scons to build lyx
988 ''' % (time.asctime(), ' '.join(sys.argv),
989 env['VERSION_INFO'].replace('\n','\n# ')) )
995 # -h will print out help info
996 Help(opts.GenerateHelpText(env))
997 # save environment settings (for fast_start option)
998 cache_file = open(env_cache_file, 'w')
999 cPickle.dump(env_cache, cache_file)
1002 #----------------------------------------------------------
1004 #----------------------------------------------------------
1007 # this has been the source of problems on some platforms...
1008 # I find that I need to supply it with full path name
1009 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1010 # this usage needs further investigation.
1011 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1013 env['BUILD_TARGETS'] = BUILD_TARGETS
1015 print "Building all targets recursively"
1017 env.SConscript('$SCONS_DIR/SConscript', duplicate = 0)