]> git.lyx.org Git - lyx.git/blob - development/scons/SConstruct
Add new tableinsertwidget
[lyx.git] / development / scons / SConstruct
1 # vi:filetype=python:expandtab:tabstop=2:shiftwidth=2
2 #
3 # file SConstruct
4 #
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7 #
8 # \author Bo Peng
9 # Full author contact details are available in file CREDITS.
10 #
11 #
12 # This is a scons based building system for lyx, you can use it as follows:
13 #
14 #   $ cd development/scons
15 #   $ scons [options] [targets]
16 # or:
17 #   $ scons -f development/scons/SConstruct [options] [targets]
18 # and:
19 #   $ scons [prefix=.] install
20 #
21 # Where:
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 
24 #     for install
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
29 #
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/
38 #
39 # Hints:
40 #   * scons fast_start=yes
41 #     If env.cache exists, bypass all tests and use existing src/config.h
42 #
43 #   * scons --config=force
44 #     force re-configuration (use scons -H for details)
45 #
46 #   * check config.log to see why config has failed
47 #
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.
52 #
53 #   * executed commands will be logged in scons_lyx.log. You can use logfile=
54 #     option to save log to another file.
55 #
56 # Notes:
57 #
58 #   * scons dist etc may be added later. Interested contributors can follow
59 #       http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/AccumulateBuilder
60 #     or
61 #       http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/DistTarBuilder
62 #     Please also see the commented out code in scons_utils.py
63 #   
64 #   * NSIS support can be found here.
65 #     http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/NsisSconsTool
66 #
67 #   * rpm support?
68 #     http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/RpmHonchoTemp
69 #
70 #   However, I decide to wait since scons seems to be standardizing these
71 #   features.
72 #
73
74 import os, sys, copy, cPickle
75
76 # config/scons_utils.py defines a few utility function
77 sys.path.append('config')
78 import scons_utils as utils
79
80 #----------------------------------------------------------
81 # Required runtime environment
82 #----------------------------------------------------------
83
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)
88
89 # determine where I am ...
90 #
91 # called as 'scons -f development/scons/SConstruct'
92 if os.path.isfile('SConstruct'):
93   TOP_SRC_DIR = '../..'
94   SCONS_DIR = '.'
95 # called as 'cd development/scons; scons'
96 else:
97   TOP_SRC_DIR = '.'
98   SCONS_DIR = 'development/scons'
99
100 #----------------------------------------------------------
101 # Global definitions
102 #----------------------------------------------------------
103
104 # some global settings
105 PACKAGE_VERSION = '1.5.0svn'
106 DEVEL_VERSION = True
107 default_build_mode = 'debug'
108
109 PACKAGE = 'lyx'
110 PACKAGE_BUGREPORT = 'lyx-devel@lists.lyx.org'
111 PACKAGE_NAME = 'LyX'
112 PACKAGE_TARNAME = 'lyx'
113 PACKAGE_STRING = '%s %s' % (PACKAGE_NAME, PACKAGE_VERSION)
114
115 # various cache/log files
116 default_log_file = 'scons_lyx.log'
117 env_cache_file = 'env.cache'
118
119
120 #----------------------------------------------------------
121 # platform dependent settings
122 #----------------------------------------------------------
123 if os.name == 'nt':
124   platform_name = 'win32'
125   default_frontend = 'qt4'
126   # boost and gettext are unlikely to be installed already
127   default_boost_opt = 'included'
128   default_gettext_opt = 'included'
129   default_pch_opt = False
130   default_with_x = False
131   spell_checker = 'auto'
132   # boost_posix indicates to boost which API to use (posix or windows).
133   # If not specified, boost tries to figure out by itself, but it may fail.
134   boost_posix = False
135   packaging_method = 'windows'
136   add_suffix_to_executables = False
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
149   boost_posix = True
150   packaging_method = 'posix'
151   add_suffix_to_executables = True
152   default_prefix = '/usr/local/'
153   share_dir = 'share/lyx'
154   man_dir = 'man/man1'
155   locale_dir = 'share/locale'
156 elif os.name == 'posix' and sys.platform == 'cygwin':
157   platform_name = 'cygwin'
158   default_frontend = 'qt3'
159   # force the use of cygwin/boost/gettext
160   default_boost_opt = 'system'
161   default_gettext_opt = 'system'
162   default_pch_opt = False
163   default_with_x = True
164   boost_posix = True
165   packaging_method = 'posix'
166   add_suffix_to_executables = True
167   default_prefix = '/usr/local/'
168   share_dir = 'share/lyx'
169   man_dir = 'man/man1'
170   locale_dir = 'share/locale'
171 elif os.name == 'darwin':
172   platform_name = 'mac'
173   default_frontend = 'qt3'
174   # to be safe
175   default_boost_opt = 'included'
176   default_gettext_opt = 'included'
177   default_pch_opt = False
178   default_with_x = False
179   boost_posix = True
180   packaging_method = 'mac'
181   add_suffix_to_executables = True
182   # FIXME: where to install?
183   default_prefix = '/usr/local/'
184   share_dir = 'Resources'
185   man_dir = 'Resources/man/man1'
186   locale_dir = 'Resources/locale'
187 else:  # unsupported system
188   platform_name = 'others'
189   default_frontend = 'qt3'
190   # to be safe
191   default_boost_opt = 'included'
192   default_gettext_opt = 'included'
193   default_pch_opt = False
194   default_with_x = True
195   boost_posix = False
196   packaging_method = 'posix'
197   add_suffix_to_executables = True
198   default_prefix = '/usr/local/'
199   share_dir = 'share/lyx'
200   man_dir = 'man/man1'
201   locale_dir = 'share/locale'
202
203
204 #---------------------------------------------------------
205 # Handling options
206 #----------------------------------------------------------
207 #
208 if os.path.isfile('config.py'):
209   print "Getting options from config.py..."
210   print open('config.py').read()
211
212 opts = Options(['config.py'])
213 opts.AddOptions(
214   # frontend,
215   EnumOption('frontend', 'Main GUI', default_frontend,
216     allowed_values = ('xform', 'qt3', 'qt4', 'gtk') ),
217   # debug or release build
218   EnumOption('mode', 'Building method', default_build_mode,
219     allowed_values = ('debug', 'release') ),
220   # boost libraries
221   EnumOption('boost',
222     'Use included, system boost library, or try sytem boost first.',
223     default_boost_opt,
224     allowed_values = (
225       'auto',       # detect boost, if not found, use included
226       'included',   # always use included boost
227       'system',     # always use system boost, fail if can not find
228       ) ),
229   # FIXME: not implemented yet.
230   EnumOption('gettext',
231     'Use included, system gettext library, or try sytem gettext first',
232     default_gettext_opt,
233     allowed_values = (
234       'auto',       # detect gettext, if not found, use included
235       'included',   # always use included gettext
236       'system',     # always use system gettext, fail if can not find
237       ) ),
238   #
239   EnumOption('spell', 'Choose spell checker to use.', 'auto',
240     allowed_values = ('aspell', 'pspell', 'ispell', 'auto') ),
241   #
242   BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
243   #
244   BoolOption('load_option', 'load option from previous scons run', True),
245   # FIXME: I do not know how pch is working. Ignore this option now.
246   BoolOption('pch', '(NA) Whether or not use pch', default_pch_opt),
247   # enable assertion, (config.h has ENABLE_ASSERTIOS
248   BoolOption('assertions', 'Use assertions', True),
249   # enable warning, (config.h has WITH_WARNINGS)
250   BoolOption('warnings', 'Use warnings', True),
251   # enable glib, (config.h has _GLIBCXX_CONCEPT_CHECKS)
252   BoolOption('concept_checks', 'Enable concept checks', True),
253   # 
254   BoolOption('nls', 'Whether or not use native language support', True),
255   # FIXME: not implemented
256   BoolOption('profile', '(NA) Whether or not enable profiling', False),
257   # FIXME: not implemented
258   BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False),
259   # using x11?
260   BoolOption('X11', 'Use x11 windows system', default_with_x),
261   # use MS VC++ to build lyx
262   BoolOption('use_vc', 'Use MS VC++ to build lyx', False),
263   #
264   PathOption('qt_dir', 'Path to qt directory', None),
265   #
266   PathOption('qt_include_path', 'Path to qt include directory', None),
267   #
268   PathOption('qt_lib_path', 'Path to qt library directory', None),
269   # build directory, will use $mode if not set
270   PathOption('build_dir', 'Build directory', None),
271   # extra include and libpath
272   PathOption('extra_inc_path', 'Extra include path', None),
273   #
274   PathOption('extra_lib_path', 'Extra library path', None),
275   #
276   PathOption('extra_inc_path1', 'Extra include path', None),
277   #
278   PathOption('extra_lib_path1', 'Extra library path', None),
279   # rebuild only specifed, comma separated targets
280   ('rebuild', 'rebuild only specifed, comma separated targets', None),
281   # can be set to a non-existing directory
282   ('prefix', 'install architecture-independent files in PREFIX', None),
283   # will install to dest_dir if defined. Otherwise, prefix will be used.
284   ('dest_dir', 'install to dest_dir', None),
285   # version suffix
286   ('version_suffix', 'install lyx as lyx-suffix', ''),
287   #
288   PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
289   # log file
290   ('logfile', 'save commands (not outputs) to logfile', default_log_file),
291   # Path to aikasurus
292   PathOption('aikasurus_path', 'Path to aikasurus library', None),
293   # environment variable can be set as options. (DO NOT set defaults)
294   ('CC', '$CC', None),
295   ('LINK', '$LINK', None),
296   ('CPP', '$CPP', None),
297   ('CXX', '$CXX', None),
298   ('CXXCPP', '$CXXCPP', None),
299   ('CCFLAGS', '$CCFLAGS', None),
300   ('CPPFLAGS', '$CPPFLAGS', None),
301   ('LDFLAGS', '$LDFLAGS', None),
302 )
303
304 # whether or not use current config.h, and cached tests
305 if (not ARGUMENTS.has_key('fast_start') or \
306   ARGUMENTS['fast_start'] in ['y', 'yes', 't', 'true', '1', 'all']) \
307   and os.path.isfile(env_cache_file):
308   fast_start = True
309   cache_file = open(env_cache_file)
310   env_cache = cPickle.load(cache_file)
311   cache_file.close()
312   print '------------ fast_start mode --------------------'
313   print '  Use cached test results and current config.h'
314   print '  use fast_start=no to override'
315   print
316 else:
317   fast_start = False
318   env_cache = {}
319
320 if (not ARGUMENTS.has_key('load_option') or \
321   ARGUMENTS['load_option'] in ['y', 'yes', 't', 'true', '1', 'all']) \
322   and os.path.isfile(env_cache_file):
323   cache_file = open(env_cache_file)
324   opt_cache = cPickle.load(cache_file)['arg_cache']
325   cache_file.close()
326   # import cached options, but we should ignore qt_dir when frontend changes
327   if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
328     and ARGUMENTS['frontend'] != opt_cache['frontend'] \
329     and opt_cache.has_key('qt_dir'):
330     opt_cache.pop('qt_dir')
331   # and we do not cache fast_start
332   if opt_cache.has_key('fast_start'):
333     opt_cache.pop('fast_start')
334   for key in opt_cache.keys():
335     if not ARGUMENTS.has_key(key):
336       ARGUMENTS[key] = opt_cache[key]
337       print "Restoring cached option  %s=%s" % (key, ARGUMENTS[key])
338   print
339
340 # save arguments
341 env_cache['arg_cache'] = ARGUMENTS
342
343
344 #---------------------------------------------------------
345 # Setting up environment
346 #---------------------------------------------------------
347
348 # Note that I do not really like ENV=os.environ, but you may 
349 # add it here if you experience some environment related problem
350 env = Environment(options = opts)
351
352 # Determine the frontend to use, which may be loaded
353 # from option cache
354 frontend = env.get('frontend', default_frontend)
355 # make sure the key exists
356 env['frontend'] = frontend
357 #
358 use_X11 = env.get('X11', default_with_x)
359 use_vc = env.get('use_vc', False)
360 # use it only once for s scons-bug, will remove it later.
361 env['USE_VC'] = use_vc
362
363
364 # set individual variables since I do not really like ENV = os.environ
365 env['ENV']['PATH'] = os.environ.get('PATH')
366 env['ENV']['HOME'] = os.environ.get('HOME')
367 # these are defined for MSVC
368 env['ENV']['LIB'] = os.environ.get('LIB')
369 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
370 env['TOP_SRC_DIR'] = TOP_SRC_DIR
371 env['SCONS_DIR'] = SCONS_DIR
372 # install to default_prefix by default
373 env['PREFIX'] = env.get('prefix', default_prefix)
374 # program suffix
375 if env.has_key('version_suffix'):
376   env['PROGRAM_SUFFIX'] = env['version_suffix']
377 else:
378   env['PROGRAM_SUFFIX'] = ''
379 env['ADD_SUFFIX_TO_EXECUTABLES'] = add_suffix_to_executables
380 env['SHARE_DIR'] = os.path.join(env['PREFIX'], share_dir + env['PROGRAM_SUFFIX'])
381 env['LOCALE_DIR'] = os.path.join(env['PREFIX'], locale_dir)
382 #
383 # if dest_dir is different from prefix.
384 env['DEST_DIR'] = env.get('dest_dir', env['PREFIX'])
385 if env.has_key('exec_prefix'):
386   env['BIN_DEST_DIR'] = env['exec_prefix']
387 else:
388   env['BIN_DEST_DIR'] = os.path.join(env['DEST_DIR'], 'bin')
389 env['SHARE_DEST_DIR'] = os.path.join(env['DEST_DIR'], share_dir + env['PROGRAM_SUFFIX'])
390 env['MAN_DEST_DIR'] = os.path.join(env['DEST_DIR'], man_dir)
391 env['LOCALE_DEST_DIR'] = os.path.join(env['DEST_DIR'], locale_dir)
392
393 #
394 # this is a bit out of place (after auto-configration) but 
395 # it is required to do the tests. Since Tool('mingw') will 
396 # reset CCFLAGS etc, this should be done before getEnvVariable
397 if platform_name == 'win32' and not use_vc:
398   env.Tool('mingw')
399   env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
400 elif use_vc:
401   env.Tool('msvc')
402   env.Tool('mslink')
403
404
405 # speed up source file processing
406 #env['CPPSUFFIXES'] = ['.C', '.cc', '.cpp']
407 #env['CXXSUFFIX'] = ['.C']
408
409 def getEnvVariable(env, name):
410   # first try command line argument (override environment settings)
411   if ARGUMENTS.has_key(name) and ARGUMENTS[name].strip() != '':
412     # multiple options may be passed like "-02 -g"
413     env[name] = ARGUMENTS[name].split()
414     # it does not seem necessary, but it is safer to change ['a'] back to 'a'
415     if len(env[name]) == 1:
416       env[name] = env[name][0]
417   # then use environment default
418   elif os.environ.has_key(name) and os.environ[name].strip() != '':
419     print "Acquiring varaible %s from system environment: %s" % (name, env[name])
420     env[name] = os.environ[name].split()
421     if len(env[name]) == 1:
422       env[name] = env[name][0]
423   # finally, env['CC'] etc is set to the default values of Options.
424   # and env['CPP'] etc does not exist
425
426 getEnvVariable(env, 'CC')
427 getEnvVariable(env, 'LINK')
428 getEnvVariable(env, 'CPP')
429 getEnvVariable(env, 'CXX')
430 getEnvVariable(env, 'CXXCPP')
431 getEnvVariable(env, 'CCFLAGS')
432 getEnvVariable(env, 'CXXFLAGS')
433 getEnvVariable(env, 'CPPFLAGS')
434 getEnvVariable(env, 'LDFLAGS')
435
436
437 #
438 # frontend, mode, BUILDDIR and LOCALLIBPATH=BUILDDIR/libs
439 #
440 env['mode'] = env.get('mode', default_build_mode)
441 # lyx will be built to $build/build_dir so it is possible
442 # to build multiple build_dirs using the same source
443 # $mode can be debug or release
444 if env.has_key('build_dir') and env['build_dir']:
445   build_dir = env['build_dir']
446   env['BUILDDIR'] = build_dir
447 else:
448   # Determine the name of the build $mode
449   env['BUILDDIR'] = '#' + env['mode']
450 # all built libraries will go to build_dir/libs
451 # (This is different from the make file approach)
452 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
453 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
454
455 #
456 # QTDIR, QT_LIB_PATH, QT_INC_PATH
457 #
458 if env.has_key('qt_dir') and env['qt_dir']:
459   env['QTDIR'] = env['qt_dir']
460   # add path to the qt tools
461   env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
462   # set environment so that moc etc can be found even if its path is not set properly
463   env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
464 else:
465   env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
466
467 if env.has_key('qt_lib_path') and env['qt_lib_path']:
468   env['QT_LIB_PATH'] = env['qt_lib_path']
469 else:
470   env['QT_LIB_PATH'] = '$QTDIR/lib'
471 env.AppendUnique(LIBPATH = ['$QT_LIB_PATH'])
472 # qt4 seems to be using pkg_config
473 env.PrependENVPath('PKG_CONFIG_PATH', env.subst('$QT_LIB_PATH'))
474
475 if env.has_key('qt_inc_path') and env['qt_inc_path']:
476   env['QT_INC_PATH'] = env['qt_inc_path']
477 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
478   env['QT_INC_PATH'] = '$QTDIR/include'
479 else: # have to guess
480   env['QT_INC_PATH'] = '/usr/include/$frontend/'
481 # Note that this CPPPATH is for testing only
482 # it will be removed before calling SConscript
483 env['CPPPATH'] = [env['QT_INC_PATH']]
484
485 #
486 # extra_inc_path and extra_lib_path
487 #
488 if env.has_key('extra_inc_path') and env['extra_inc_path']:
489   env.AppendUnique(CPPPATH = [env['extra_inc_path']])
490 if env.has_key('extra_lib_path') and env['extra_lib_path']:
491   env.AppendUnique(LIBPATH = [env['extra_lib_path']])
492 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
493   env.AppendUnique(CPPPATH = [env['extra_inc_path1']])
494 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
495   env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
496 if env.has_key('aikasurus_path') and env['aikasurus_path']:
497   env.AppendUnique(LIBPATH = [env['aikasurus_path']])
498
499
500 # under windows, scons is confused by .C/.c and uses gcc instead of
501 # g++. I am forcing the use of g++ here. This is expected to change
502 # after lyx renames all .C files to .cpp
503 #
504 # Note that this step has to be after env.Tool('mingw') step
505 # since env.Tool('mingw') will set env['CC'] etc.
506 #
507 # save the old c compiler and CCFLAGS (used by libintl)
508 env['C_COMPILER'] = env.subst('$CC')
509 env['C_CCFLAGS'] = env.subst('$CCFLAGS')
510 # if we use ms vc, the commands are fine (cl.exe and link.exe)
511 if not use_vc:
512   if env.has_key('CXX') and env['CXX']:
513     env['CC'] = env.subst('$CXX')
514     env['LINK'] = env.subst('$CXX')
515   else:
516     env['CC'] = 'g++'
517     env['LINK'] = 'g++'
518 else: 
519   # /TP treat all source code as C++
520   # C4819: The file contains a character that cannot be represented 
521   #   in the current code page (number)
522   # C4996: foo was decleared deprecated
523   env.Append(CCFLAGS=['/TP', '/EHsc', '/wd4819', '/wd4996'])
524
525
526 #----------------------------------------------------------
527 # Autoconf business
528 #----------------------------------------------------------
529
530 conf = Configure(env,
531   custom_tests = {
532     'CheckPkgConfig' : utils.checkPkgConfig,
533     'CheckPackage' : utils.checkPackage,
534     'CheckMkdirOneArg' : utils.checkMkdirOneArg,
535     'CheckSelectArgType' : utils.checkSelectArgType,
536     'CheckBoostLibraries' : utils.checkBoostLibraries,
537     'CheckCommand' : utils.checkCommand,
538     'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
539   }
540 )
541
542 # pkg-config? (if not, we use hard-coded options)
543 if not fast_start:
544   if conf.CheckPkgConfig('0.15.0'):
545     env['HAS_PKG_CONFIG'] = True
546   else:
547     print 'pkg-config >= 0.1.50 is not found'
548     env['HAS_PKG_CONFIG'] = False
549   env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
550 else:
551   env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
552
553 # zlib? This is required. (fast_start assumes the existance of zlib)
554 if not fast_start and not conf.CheckLibWithHeader('z', 'zlib.h', 'C'):
555     print 'Did not find libz or zlib.h, exiting!'
556     Exit(1)
557
558 # qt libraries?
559 if not fast_start:
560   #
561   # qt3 does not use pkg_config
562   if frontend == 'qt3':
563     if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
564       print 'Did not find qt libraries, exiting!'
565       Exit(1)
566   elif frontend == 'qt4':
567     succ = False
568     # first: try pkg_config
569     if env['HAS_PKG_CONFIG']:
570       succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
571       env['QT4_PKG_CONFIG'] = succ
572     # second: try to link to it
573     if not succ:
574       # FIXME: under linux, I can test the following perfectly
575       # However, under windows, lib names need to passed as libXXX4.a ...
576       succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
577         conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
578     # third: try to look up the path
579     if not succ:
580       succ = True
581       for lib in ['QtCore', 'QtGui']:
582         # windows version has something like QtGui4 ...
583         if not (os.path.isfile(os.path.join(env.subst('$QT_LIB_PATH'), 'lib%s.a' % lib)) or \
584           os.path.isfile(os.path.join(env.subst('$QT_LIB_PATH'), 'lib%s4.a' % lib))):
585           succ = False
586           break
587     # still can not find it
588     if succ:
589       print "Qt4 libraries are found."
590     else:
591       print 'Did not find qt libraries, exiting!'
592       Exit(1)
593
594
595 # check socket libs
596 if not fast_start:
597   env['SOCKET_LIBS'] = []
598   if conf.CheckLib('socket'):
599     env['SOCKET_LIBS'].append('socket')
600
601   # nsl is the network services library and provides a
602   # transport-level interface to networking services.
603   if conf.CheckLib('nsl'):
604     env['SOCKET_LIBS'].append('nsl')
605
606   env_cache['SOCKET_LIBS'] = env['SOCKET_LIBS']
607 else:
608   env['SOCKET_LIBS'] = env_cache['SOCKET_LIBS']
609
610 if not fast_start:
611   # check boost libraries
612   boost_opt = ARGUMENTS.get('boost', default_boost_opt)
613   # check for system boost
614   succ = False
615   if boost_opt in ['auto', 'system']:
616     pathes = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
617     sig = conf.CheckBoostLibraries('boost_signals', pathes)
618     reg = conf.CheckBoostLibraries('boost_regex', pathes)
619     fil = conf.CheckBoostLibraries('boost_filesystem', pathes)
620     ios = conf.CheckBoostLibraries('boost_iostreams', pathes)
621     # if any of them is not found
622     if ('' in [sig[0], reg[0], fil[0], ios[0]]):
623       if boost_opt == 'system':
624         print "Can not find system boost libraries"
625         print "Please supply a path through extra_lib_path and try again."
626         print "Or use boost=included to use included boost libraries."
627         Exit(2)
628     else:
629       env['BOOST_LIBRARIES'] = [sig[1], reg[1], fil[1], ios[1]]
630       # assume all boost libraries are in the same path...
631       env.AppendUnique(LIBPATH = [sig[0]])
632       env['INCLUDED_BOOST'] = False
633       succ = True
634   # now, auto and succ = false, or boost=included
635   if not succ:
636     # we do not need to set LIBPATH now.
637     env['BOOST_LIBRARIES'] = ['included_boost_signals', 'included_boost_regex',
638       'included_boost_filesystem', 'included_boost_iostreams']
639     env['INCLUDED_BOOST'] = True
640   env_cache['BOOST_LIBRARIES'] = env['BOOST_LIBRARIES']
641   env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
642 else:
643   env['BOOST_LIBRARIES'] = env_cache['BOOST_LIBRARIES']
644   env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
645
646
647 env['ENABLE_NLS'] = not env.has_key('nls') or env['nls']
648
649 if not fast_start:
650   if not env['ENABLE_NLS']:
651     env['INTL_LIBS'] = []
652     env['INCLUDED_GETTEXT'] = False
653   else:
654     # check gettext libraries
655     gettext_opt = ARGUMENTS.get('gettext', default_gettext_opt)
656     # check for system gettext
657     succ = False
658     if gettext_opt in ['auto', 'system']:
659       if conf.CheckLib('intl'):
660         env['INCLUDED_GETTEXT'] = False
661         env['INTL_LIBS'] = ['intl']
662         succ = True
663       else: # no found
664         if gettext_opt == 'system':
665           print "Can not find system gettext library"
666           print "Please supply a path through extra_lib_path and try again."
667           print "Or use gettext=included to use included gettext libraries."
668           Exit(2)
669     # now, auto and succ = false, or gettext=included
670     if not succ:
671       # we do not need to set LIBPATH now.
672       env['INCLUDED_GETTEXT'] = True
673       env['INTL_LIBS'] = ['included_intl']
674     if platform_name == 'win32' and not use_vc:
675       # for functions AddFontResouceA, RemoveFontResourceA
676       # if use_vc, gdi32 will be added anyway later
677       env['INTL_LIBS'].append('gdi32')
678   env_cache['INCLUDED_GETTEXT'] = env['INCLUDED_GETTEXT']
679   env_cache['INTL_LIBS'] = env['INTL_LIBS']
680 else:
681   env['INTL_LIBS'] = env_cache['INTL_LIBS']
682   env['INCLUDED_GETTEXT'] = env_cache['INCLUDED_GETTEXT']
683
684 #
685 # check for msgfmt command
686 if not fast_start:
687   env['MSGFMT'] = conf.CheckCommand('msgfmt')
688   env_cache['MSGFMT'] = env['MSGFMT']
689 else:
690   env['MSGFMT'] = env_cache['MSGFMT']
691
692
693 #----------------------------------------------------------
694 # Generating config.h
695 #----------------------------------------------------------
696 if not fast_start:
697   print "Generating ", utils.config_h, "..."
698
699   # I do not handle all macros in src/config.h.in, rather I am following a list
700   # of *used-by-lyx* macros compiled by Abdelrazak Younes <younes.a@free.fr>
701   #
702   # Note: addToConfig etc are defined in scons_util
703   utils.startConfigH()
704
705   # HAVE_IO_H
706   # HAVE_LIMITS_H
707   # HAVE_LOCALE_H
708   # HAVE_LOCALE
709   # HAVE_PROCESS_H
710   # HAVE_STDLIB_H
711   # HAVE_SYS_STAT_H
712   # HAVE_SYS_TIME_H
713   # HAVE_SYS_TYPES_H
714   # HAVE_SYS_UTIME_H
715   # HAVE_UNISTD_H
716   # HAVE_UTIME_H
717   # HAVE_STRINGS_H
718   # HAVE_DIRECT_H
719   # HAVE_ISTREAM
720   # HAVE_OSTREAM
721   # HAVE_IOS
722
723   # for libintl % grep HAVE * | grep _H | cut -d: -f2 | sort -u
724   
725   # HAVE_STDINT_H_WITH_UINTMAX
726   # HAVE_INTTYPES_H_WITH_UINTMAX
727   # 
728   # HAVE_INTTYPES_H
729   # HAVE_STDINT_H
730   # HAVE_ALLOCA_H
731   # HAVE_STDLIB_H
732   # HAVE_STRING_H
733   # HAVE_STDDEF_H
734   # HAVE_LIMITS_H
735   # HAVE_ARGZ_H
736   # HAVE_UNISTD_H
737   # HAVE_SYS_PARAM_H
738
739   # Check header files
740   headers = [
741     ('io.h', 'HAVE_IO_H', 'c'),
742     ('limits.h', 'HAVE_LIMITS_H', 'c'),
743     ('locale.h', 'HAVE_LOCALE_H', 'c'),
744     ('locale', 'HAVE_LOCALE', 'cxx'),
745     ('process.h', 'HAVE_PROCESS_H', 'c'),
746     ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
747     ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
748     ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
749     ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
750     ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
751     ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
752     ('unistd.h', 'HAVE_UNISTD_H', 'c'),
753     ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
754     ('utime.h', 'HAVE_UTIME_H', 'c'),
755     ('string.h', 'HAVE_STRING_H', 'c'),
756     ('strings.h', 'HAVE_STRINGS_H', 'c'),
757     ('direct.h', 'HAVE_DIRECT_H', 'c'),
758     ('istream', 'HAVE_ISTREAM', 'cxx'),
759     ('ostream', 'HAVE_OSTREAM', 'cxx'),
760     ('ios', 'HAVE_IOS', 'cxx'),
761     ('argz.h', 'HAVE_ARGZ_H', 'c'),
762     ('limits.h', 'HAVE_LIMITS_H', 'c'),
763     ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
764     ('stddef.h', 'HAVE_STDDEF_H', 'c'),
765     ('stdint.h', 'HAVE_STDINT_H', 'c'),
766     ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c')
767   ]
768
769   for header in headers:
770     utils.addToConfig("/* Define to 1 if you have the <%s> header file. */" % header[0], newline=1)
771     if (header[2] == 'c' and conf.CheckCHeader(header[0])) or \
772       (header[2] == 'cxx' and conf.CheckCXXHeader(header[0])):
773       utils.addToConfig('#define %s 1' % header[1])
774     else:
775       utils.addToConfig('/* #undef %s */' % header[1])
776
777   # HAVE_OPEN
778   # HAVE_CLOSE
779   # HAVE_POPEN
780   # HAVE_PCLOSE
781   # HAVE__OPEN
782   # HAVE__CLOSE
783   # HAVE__POPEN
784   # HAVE__PCLOSE
785   # HAVE_GETPID
786   # HAVE__GETPID
787   # HAVE_MKDIR
788   # HAVE__MKDIR
789   # HAVE_PUTENV
790   # HAVE_MKTEMP
791   # HAVE_MKSTEMP
792   # HAVE_STRERROR
793   # HAVE_STD_COUNT
794   # HAVE_GETCWD
795   # HAVE_STRCPY
796   # HAVE_STRCASECMP 
797   # HAVE_STRDUP
798   # HAVE_STRTOUL
799   # HAVE_WCSLEN
800   # HAVE_MMAP ?
801   # HAVE_ALLOCA
802   # HAVE___FSETLOCKING
803   # HAVE_MEMPCPY
804   # HAVE_STRCASECMP
805   # HAVE___ARGZ_COUNT
806   # HAVE___ARGZ_NEXT
807   # HAVE___ARGZ_STRINGIFY
808   # HAVE___FSETLOCKING
809   # HAVE_GETCWD 
810   # HAVE_STRTOUL  
811   # HAVE_STRCASECMP
812   # HAVE_STRDUP
813   # HAVE_TSEARCH 
814
815   # Check functions
816   functions = [
817     ('open', 'HAVE_OPEN', None),
818     ('close', 'HAVE_CLOSE', None),
819     ('popen', 'HAVE_POPEN', None),
820     ('pclose', 'HAVE_PCLOSE', None),
821     ('_open', 'HAVE__OPEN', None),
822     ('_close', 'HAVE__CLOSE', None),
823     ('_popen', 'HAVE__POPEN', None),
824     ('_pclose', 'HAVE__PCLOSE', None),
825     ('getpid', 'HAVE_GETPID', None),
826     ('_getpid', 'HAVE__GETPID', None),
827     ('mkdir', 'HAVE_MKDIR', None),
828     ('_mkdir', 'HAVE__MKDIR', None),
829     ('putenv', 'HAVE_PUTENV', None),
830     ('mktemp', 'HAVE_MKTEMP', None),
831     ('mkstemp', 'HAVE_MKSTEMP', None),
832     ('strerror', 'HAVE_STRERROR', None),
833     ('count', 'HAVE_STD_COUNT', '''
834 #include <algorithm>
835 int count()
836 {
837   char a[] = "hello";
838   return std::count(a, a+5, 'l');
839 }
840 '''),
841     ('getcwd', 'HAVE_GETCWD', None),
842     ('stpcpy', 'HAVE_STPCPY', None),
843     ('strcasecmp', 'HAVE_STRCASECMP', None),
844     ('strdup', 'HAVE_STRDUP', None),
845     ('strtoul', 'HAVE_STRTOUL', None),
846     ('alloca', 'HAVE_ALLOCA', None),
847     ('__fsetlocking', 'HAVE___FSETLOCKING', None),
848     ('mempcpy', 'HAVE_MEMPCPY', None),
849     ('__argz_count', 'HAVE___ARGZ_COUNT', None),
850     ('__argz_next', 'HAVE___ARGZ_NEXT', None),
851     ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
852     ('setlocale', 'HAVE_SETLOCALE', None),
853     ('tsearch', 'HAVE_TSEARCH', None),
854     ('getegid', 'HAVE_GETEGID', None),
855     ('getgid', 'HAVE_GETGID', None),
856     ('getuid', 'HAVE_GETUID', None),
857     ('wcslen', 'HAVE_WCSLEN', None)
858   ]
859
860   # HAVE_ASPRINTF
861   # HAVE_WPRINTF
862   # HAVE_SNPRINTF
863   # HAVE_POSIX_PRINTF
864   # HAVE_FCNTL
865   
866   for func in functions:
867     utils.addToConfig("/* Define to 1 if you have the `%s' function. */" % func[0], newline=1)
868     if conf.CheckFunc(func[0], header=func[2]):
869       utils.addToConfig('#define %s 1' % func[1])
870     else:
871       utils.addToConfig('/* #undef %s */' % func[1])
872
873   env_functions = [
874     ('asprintf', 'HAVE_ASPRINTF'),
875     ('wprintf', 'HAVE_WPRINTF'),
876     ('snprintf', 'HAVE_SNPRINTF'),
877     ('printf', 'HAVE_POSIX_PRINTF'),
878     ('fcntl', 'HAVE_FCNTL')
879   ]
880
881   for func in env_functions:
882     utils.addToConfig("/* Define to 1 if you have the `%s' function. */" % func[0], newline=1)
883     if conf.CheckFunc(func[0]):
884       utils.addToConfig('#define %s 1' % func[1])
885       env[func[1]] = 1
886     else:
887       utils.addToConfig('/* #undef %s */' % func[1])
888       env[func[1]] = 0
889
890   # HAVE_INTMAX_T
891   # HAVE_INTTYPES_H_WITH_UINTMAX 
892   # HAVE_DECL_ISTREAMBUF_ITERATOR
893   utils.addToConfig("/* Define to 1 if you have the `intmax_t' type. */", newline=1)
894   if conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
895     conf.CheckType('intmax_t', includes='#include <inttypes.h>'):
896     utils.addToConfig('#define HAVE_INTMAX_T 1')
897   else:
898     utils.addToConfig('/* #undef HAVE_INTMAX_T */')
899
900   # HAVE_INTMAX_T
901   # HAVE_LONG_DOUBLE
902   # HAVE_LONG_LONG
903   # HAVE_WCHAR_T
904   # HAVE_WINT_T
905   # HAVE_INTTYPES_H_WITH_UINTMAX 
906   
907   types = [
908     ('intmax_t', 'HAVE_INTMAX_T', None),
909     ('long double', 'HAVE_LONG_DOUBLE', None),
910     ('long long', 'HAVE_LONG_LONG', None),
911     ('wchar_t', 'HAVE_WCHAR_T', None),
912     ('wint_t', 'HAVE_WINT_T', None),
913     ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
914     ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
915       '#include <streambuf>\n#include <istream>')
916   ]
917   for t in types: 
918     utils.addToConfig("/* Define to 1 if you have the `%s' type. */" % t[0], newline=1)
919     if conf.CheckType(t[0], includes=t[2]):
920       utils.addToConfig('#define %s 1' % t[1])
921     else:
922       utils.addToConfig('/* #undef %s */' % t[1])
923
924   # windows/msvc sys/types.h does not have pid_t
925   # FIXME: #include <windows.h> is the right way?
926   if not conf.CheckType('pid_t', includes='#include <sys/types.h>'):
927     utils.addToConfig('#define pid_t int')
928   
929   # determine the use of std::tolower or tolower
930   if conf.CheckCXXGlobalCstd():
931     utils.addToConfig('#define CXX_GLOBAL_CSTD 1')
932   else:
933     utils.addToConfig('/* #undef CXX_GLOBAL_CSTD */')
934
935   # PACKAGE
936   # PACKAGE_VERSION
937   # DEVEL_VERSION
938   utils.addToConfig('#define PACKAGE "%s%s"' % (PACKAGE, env['PROGRAM_SUFFIX']))
939   utils.addToConfig('#define PACKAGE_VERSION "%s"' % PACKAGE_VERSION)
940   if DEVEL_VERSION:
941     utils.addToConfig('#define DEVEL_VERSION 1')
942
943   # ENABLE_ASSERTIONS
944   # ENABLE_NLS
945   # WITH_WARNINGS
946   # _GLIBCXX_CONCEPT_CHECKS
947
948   # items are (ENV, ARGUMENTS)
949   values = [
950     ('ENABLE_ASSERTIONS', 'assertions'),
951     ('ENABLE_NLS', 'nls'),
952     ('WITH_WARNINGS', 'warnings'),
953     ('_GLIBCXX_CONCEPT_CHECKS', 'concept_checks'),
954   ]
955
956   for val in values:
957     if (env.has_key(val[0]) and env[val[0]]) or \
958        (env.has_key(val[1]) and env[val[1]]):
959       utils.addToConfig('#define %s 1' % val[0])
960     else:
961       utils.addToConfig('/* #undef %s */' % val[0])
962
963   # disable automatic linking of boost libraries.
964   # This is an interesting feature that is supposed to be useful under
965   # windows but since I can not find a way to use it on all platforms, 
966   # I disable it for now.
967   utils.addToConfig('#define BOOST_ALL_NO_LIB 1')
968
969   env['EXTRA_LIBS'] = []
970   # HAVE_LIBAIKSAURUS
971   # AIKSAURUS_H_LOCATION
972   if conf.CheckLib('Aiksaurus'):
973     utils.addToConfig("#define HAVE_LIBAIKSAURUS 1")
974     if (conf.CheckCXXHeader("Aiksaurus.h")):
975       utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus.h>")
976     elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
977       utils.addToConfig("#define AIKSAURUS_H_LOCATION <Aiksaurus/Aiksaurus.h>")
978     else:
979       utils.addToConfig("#define AIKSAURUS_H_LOCATION")
980     env['EXTRA_LIBS'].append('Aiksaurus')
981
982   # USE_ASPELL
983   # USE_PSPELL
984   # USE_ISPELL
985
986   # determine headers to use
987   spell_engine = ARGUMENTS.get('spell', 'auto')
988   spell_detected = False
989   if spell_engine in ['auto', 'aspell'] and \
990     conf.CheckLib('aspell'):
991     utils.addToConfig('#define USE_ASPELL 1')
992     env['USE_ASPELL'] = True
993     env['USE_PSPELL'] = False
994     env['USE_ISPELL'] = False
995     env['EXTRA_LIBS'].append('aspell')
996     spell_detected = True
997   elif spell_engine in ['auto', 'pspell'] and \
998     conf.CheckLib('pspell'):
999     utils.addToConfig('#define USE_PSPELL 1')
1000     env['USE_ASPELL'] = False
1001     env['USE_PSPELL'] = True
1002     env['USE_ISPELL'] = False
1003     env['EXTRA_LIBS'].append('pspell')
1004     spell_detected = True
1005   elif spell_engine in ['auto', 'ispell'] and \
1006     conf.CheckLib('ispell'):
1007     utils.addToConfig('#define USE_ISPELL 1')
1008     env['USE_ASPELL'] = False
1009     env['USE_PSPELL'] = False
1010     env['USE_ISPELL'] = True
1011     env['EXTRA_LIBS'].append('ispell')
1012     spell_detected = True
1013
1014   if not spell_detected:
1015     env['USE_ASPELL'] = False
1016     env['USE_PSPELL'] = False
1017     env['USE_ISPELL'] = False
1018     # FIXME: can lyx work without an spell engine
1019     if spell_engine == 'auto':
1020       print "Warning: Can not locate any spell checker"
1021     else:
1022       print "Warning: Can not locate specified spell checker:", spell_engine
1023
1024   # USE_POSIX_PACKAGING
1025   # USE_MACOSX_PACKAGING
1026   # USE_WINDOWS_PACKAGING
1027   if packaging_method == 'windows':
1028     utils.addToConfig('#define USE_WINDOWS_PACKAGING 1')
1029   elif packaging_method == 'posix':
1030     utils.addToConfig('#define USE_POSIX_PACKAGING 1')
1031   elif packaging_method == 'mac':
1032     utils.addToConfig('#define USE_MACOSX_PACKAGING 1')
1033
1034   # BOOST_POSIX
1035   if boost_posix:
1036     utils.addToConfig('#define BOOST_POSIX 1')
1037   else:
1038     utils.addToConfig('/* #undef BOOST_POSIX */')
1039
1040   # MKDIR_TAKES_ONE_ARG
1041   if conf.CheckMkdirOneArg():
1042     utils.addToConfig('#define MKDIR_TAKES_ONE_ARG 1')
1043   else:
1044     utils.addToConfig('/* #undef MKDIR_TAKES_ONE_ARG */')
1045
1046   # SELECT_TYPE_ARG1
1047   # SELECT_TYPE_ARG234
1048   # SELECT_TYPE_ARG5
1049   (arg1, arg234, arg5) = conf.CheckSelectArgType()
1050   utils.addToConfig('#define SELECT_TYPE_ARG1 %s' % arg1)
1051   utils.addToConfig('#define SELECT_TYPE_ARG234 %s' % arg234)
1052   utils.addToConfig('#define SELECT_TYPE_ARG5 %s' % arg5)
1053
1054   # mkstemp
1055   # USE_BOOST_FORMAT
1056   # WANT_GETFILEATTRIBUTESEX_WRAPPER
1057   utils.endConfigH(TOP_SRC_DIR)
1058
1059   # env['EXTRA_LIBS'] will be modified later, so a unique copy is needed
1060   # NOTE that we do *not* save qt_libs in environment.
1061   env_cache['EXTRA_LIBS'] = copy.copy(env['EXTRA_LIBS'])
1062   env_cache['USE_ASPELL'] = env['USE_ASPELL']
1063   env_cache['USE_PSPELL'] = env['USE_PSPELL']
1064   env_cache['USE_ISPELL'] = env['USE_ISPELL']
1065   env_cache['HAVE_ASPRINTF'] = env['HAVE_ASPRINTF']
1066   env_cache['HAVE_WPRINTF'] = env['HAVE_WPRINTF']
1067   env_cache['HAVE_SNPRINTF'] = env['HAVE_SNPRINTF']
1068   env_cache['HAVE_POSIX_PRINTF'] = env['HAVE_POSIX_PRINTF']
1069   env_cache['HAVE_FCNTL'] = env['HAVE_FCNTL']
1070
1071 else:
1072   #
1073   # this comes as a big surprise, without this line 
1074   # (doing nothing obvious), adding fast_start=yes
1075   # to a build with fast_start=no will result in a rebuild
1076   # Note that the exact header file to check does not matter
1077   conf.CheckCHeader('io.h')
1078   # only a few variables need to be rescanned
1079   env['EXTRA_LIBS'] = copy.copy(env_cache['EXTRA_LIBS'])
1080   env['USE_ASPELL'] = env_cache['USE_ASPELL']
1081   env['USE_PSPELL'] = env_cache['USE_PSPELL']
1082   env['USE_ISPELL'] = env_cache['USE_ISPELL']
1083   env['HAVE_ASPRINTF'] = env_cache['HAVE_ASPRINTF']
1084   env['HAVE_WPRINTF'] = env_cache['HAVE_WPRINTF']
1085   env['HAVE_SNPRINTF'] = env_cache['HAVE_SNPRINTF']
1086   env['HAVE_POSIX_PRINTF'] = env_cache['HAVE_POSIX_PRINTF']
1087   env['HAVE_FCNTL'] = env_cache['HAVE_FCNTL']
1088
1089 #
1090 # Finish auto-configuration
1091 env = conf.Finish()
1092
1093 #----------------------------------------------------------
1094 # Now set up our build process accordingly
1095 #----------------------------------------------------------
1096
1097 #
1098 # QT_LIB etc (EXTRA_LIBS holds lib for each frontend)
1099 #
1100 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1101 # in their respective directory and specialized env.
1102 try:
1103   if frontend == 'qt3':
1104     # note: env.Tool('qt') my set QT_LIB to qt
1105     env['QT_LIB'] = 'qt-mt'
1106     env['EXTRA_LIBS'].append('qt-mt')
1107     if platform_name == 'cygwin' and use_X11:
1108       env['EXTRA_LIBS'].extend(['GL',  'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1109         'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1110         'pthread'])
1111       env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1112   elif frontend == 'qt4':
1113     if platform_name == "win32":
1114       env['QT_LIB'] = ['QtCore4', 'QtGui4']
1115     else:
1116       env['QT_LIB'] = ['QtCore', 'QtGui']
1117     env['EXTRA_LIBS'] += env['QT_LIB']
1118 except:
1119   print "Can not locate qt tools"
1120   print "What I get is "
1121   print "  QTDIR: ", env['QTDIR']
1122
1123
1124 if platform_name in ['win32', 'cygwin']:
1125   # the final link step needs stdc++ to succeed under mingw
1126   # FIXME: shouldn't g++ automatically link to stdc++?
1127   env['SYSTEM_LIBS'] = ['shlwapi', 'z']
1128   if use_vc:
1129     env['SYSTEM_LIBS'].extend(['gdi32', 'shell32', 'advapi32'])
1130   else:
1131     env['SYSTEM_LIBS'].append('stdc++')
1132 else:
1133   env['SYSTEM_LIBS'] = ['z']
1134
1135 #
1136 # Build parameters CPPPATH etc
1137 #
1138 # boost is always in, src is needed for config.h
1139
1140 # QT_INC_PATH is not needed for *every* source file
1141 env['CPPPATH'].remove(env['QT_INC_PATH'])
1142 env['CPPPATH'] += ['$TOP_SRC_DIR/boost', '$TOP_SRC_DIR/src']
1143
1144 # TODO: add (more) appropriate compiling options (-DNDEBUG etc)
1145 # for debug/release mode
1146 if ARGUMENTS.get('mode', default_build_mode) == 'debug':
1147   env.AppendUnique(CCFLAGS = [])
1148 else:
1149   env.AppendUnique(CCFLAGS = [])
1150
1151 #
1152 # Customized builders
1153 #
1154 # install customized builders
1155 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
1156
1157 #
1158 # A Link script for cygwin see
1159 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1160 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1161 # for details
1162 #
1163 if platform_name == 'cygwin':
1164   ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1165   ld_script = utils.installCygwinLDScript(ld_script_path)
1166   env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1167     '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1168
1169 #
1170 # Report results
1171 #
1172 # src/support/package.C.in needs the following to replace
1173 #  LYX_ABS_INSTALLED_DATADIR (e.g. /usr/local/lyx/share/lyx)
1174 env['LYX_DIR'] = env['SHARE_DIR']
1175 #  LYX_ABS_INSTALLED_LOCALEDIR
1176 env['LOCALEDIR'] = env['LOCALE_DIR']
1177 env['TOP_SRCDIR'] = env['TOP_SRC_DIR']
1178 # needed by src/version.C.in => src/version.C
1179 env['PACKAGE_VERSION'] = PACKAGE_VERSION
1180 # fill in the version info
1181 env['VERSION_INFO'] = '''Configuration
1182   Host type:                      %s
1183   Special build flags:            %s
1184   C   Compiler:                   %s
1185   C   Compiler flags:             %s %s
1186   C++ Compiler:                   %s
1187   C++ Compiler LyX flags:         %s
1188   C++ Compiler flags:             %s %s
1189   Linker flags:                   %s
1190   Linker user flags:              %s
1191 Build info:
1192   Builing directory:              %s
1193   Local library directory:        %s
1194   Libraries pathes:               %s
1195   Boost libraries:                %s
1196   Extra libraries:                %s
1197   System libraries:               %s
1198   include search path:            %s
1199 Frontend:
1200   Frontend:                       %s
1201   Packaging:                      %s
1202   LyX dir:                        %s
1203   LyX binary dir:                 %s
1204   LyX files dir:                  %s
1205 ''' % (platform_name,
1206   env.subst('$CCFLAGS'), env.subst('$CC'),
1207   env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1208   env.subst('$CXX'), env.subst('$CXXFLAGS'),
1209   env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1210   env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1211   env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1212   str(env['LIBPATH']), str(env['BOOST_LIBRARIES']),
1213   str(env['EXTRA_LIBS']), str(env['SYSTEM_LIBS']), str(env['CPPPATH']),
1214   env['frontend'], packaging_method,
1215   env['PREFIX'], env['BIN_DEST_DIR'], env['SHARE_DIR'])
1216
1217 if env['frontend'] in ['qt3', 'qt4']:
1218   env['VERSION_INFO'] += '''  include dir:                    %s
1219   library dir:                    %s
1220   X11:                            %s
1221 ''' % (env.subst('$QT_INC_PATH'), env.subst('$QT_LIB_PATH'), use_X11)
1222
1223 if not fast_start:
1224   print env['VERSION_INFO']
1225
1226 #
1227 # Mingw command line may be too short for our link usage,
1228 # Here we use a trick from scons wiki
1229 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1230 #
1231 # I also would like to add logging (commands only) capacity to the
1232 # spawn system.
1233 logfile = env.get('logfile', default_log_file)
1234 if logfile != '' or platform_name == 'win32':
1235   import time
1236   utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1237     info = '''# This is a log of commands used by scons to build lyx
1238 # Time: %s
1239 # Command: %s
1240 # Info: %s
1241 ''' % (time.asctime(), ' '.join(sys.argv),
1242   env['VERSION_INFO'].replace('\n','\n# ')) )
1243
1244
1245 #
1246 # Cleanup stuff
1247 #
1248 # -h will print out help info
1249 Help(opts.GenerateHelpText(env))
1250 # save environment settings (for fast_start option)
1251 cache_file = open(env_cache_file, 'w')
1252 cPickle.dump(env_cache, cache_file)
1253 cache_file.close()
1254
1255 #----------------------------------------------------------
1256 # Start building
1257 #----------------------------------------------------------
1258 Export('env')
1259
1260 # this has been the source of problems on some platforms...
1261 # I find that I need to supply it with full path name
1262 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1263 # this usage needs further investigation.
1264 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1265
1266 env['BUILD_TARGETS'] = BUILD_TARGETS
1267 if env.has_key('rebuild'):
1268   env['REBUILD_TARGETS'] = env['rebuild'].split(',')
1269 else:
1270   env['REBUILD_TARGETS'] = None
1271
1272 print "Building all targets recursively"
1273
1274 env.SConscript('$SCONS_DIR/SConscript', duplicate = 0)
1275
1276