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