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