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