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