]> git.lyx.org Git - features.git/blob - development/scons/SConstruct
Scons: imerge SConscript to SConstruct, separate config.h, code cleanup
[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 # This is a scons based building system for lyx, please refer
12 # to INSTALL.scons for detailed instructions.
13 #
14
15 import os, sys, copy, cPickle, glob
16
17 # config/scons_utils.py defines a few utility function
18 sys.path.append('config')
19 import scons_utils as utils
20
21 #----------------------------------------------------------
22 # Required runtime environment
23 #----------------------------------------------------------
24
25 # scons asks for 1.5.2, lyx requires 2.3
26 EnsurePythonVersion(2, 3)
27 # Please use at least 0.96.91 (not 0.96.1)
28 EnsureSConsVersion(0, 96)
29
30 # determine where I am ...
31 #
32 # called as 'scons -f development/scons/SConstruct'
33 if os.path.isfile('SConstruct'):
34   top_src_dir = '../..'
35   scons_dir = '.'
36 # called as 'cd development/scons; scons'
37 else:
38   top_src_dir = '.'
39   scons_dir = 'development/scons'
40
41
42 #----------------------------------------------------------
43 # Global definitions
44 #----------------------------------------------------------
45
46 # some global settings
47 #
48 # detect version of lyx
49 # only 1.4.x has frontends/qt2
50 if os.path.isdir(os.path.join(top_src_dir, 'src', 'frontends', 'qt2')):
51   package_version = '1.4.2svn'
52 else:
53   package_version = '1.5.0svn'
54
55 devel_version = True
56 default_build_mode = 'debug'
57 lyx_ext = '*.C'
58
59 package = 'lyx'
60 package_bugreport = 'lyx-devel@lists.lyx.org'
61 package_name = 'LyX'
62 package_tarname = 'lyx'
63 package_string = '%s %s' % (package_name, package_version)
64
65 # various cache/log files
66 default_log_file = 'scons_lyx.log'
67 env_cache_file = 'env.cache'
68
69
70 #----------------------------------------------------------
71 # platform dependent settings
72 #----------------------------------------------------------
73
74 if os.name == 'nt':
75   platform_name = 'win32'
76   default_frontend = 'qt4'
77   default_prefix = 'c:/program files/lyx'
78   default_with_x = False
79   default_packaging_method = 'windows'
80 elif os.name == 'posix' and sys.platform != 'cygwin':
81   platform_name = sys.platform
82   default_frontend = 'qt3'
83   default_prefix = '/usr/local'
84   default_with_x = True
85   default_packaging_method = 'posix'
86 elif os.name == 'posix' and sys.platform == 'cygwin':
87   platform_name = 'cygwin'
88   default_frontend = 'qt3'
89   default_prefix = '/usr/local'
90   default_with_x = True
91   default_packaging_method = 'posix'
92 elif os.name == 'darwin':
93   platform_name = 'macosx'
94   default_frontend = 'qt3'
95   # FIXME: macOSX default prefix?
96   default_prefix = '.'
97   default_with_x = False
98   default_packaging_method = 'macosx'
99 else:  # unsupported system, assume posix behavior
100   platform_name = 'others'
101   default_frontend = 'qt3'
102   default_prefix = '.'
103   default_with_x = True
104   default_packaging_method = 'posix'
105
106
107 #---------------------------------------------------------
108 # Handling options
109 #----------------------------------------------------------
110 #
111 # You can set perminant default values in config.py
112 if os.path.isfile('config.py'):
113   print "Getting options from config.py..."
114   print open('config.py').read()
115
116 opts = Options(['config.py'])
117 opts.AddOptions(
118   # frontend,
119   EnumOption('frontend', 'Main GUI', default_frontend,
120     allowed_values = ('xform', 'qt2', 'qt3', 'qt4', 'gtk') ),
121   # debug or release build
122   EnumOption('mode', 'Building method', default_build_mode,
123     allowed_values = ('debug', 'release') ),
124   # boost libraries
125   EnumOption('boost',
126     'Use included, system boost library, or try sytem boost first.',
127     'auto', allowed_values = (
128       'auto',       # detect boost, if not found, use included
129       'included',   # always use included boost
130       'system',     # always use system boost, fail if can not find
131       ) ),
132   #
133   EnumOption('gettext',
134     'Use included, system gettext library, or try sytem gettext first',
135     'auto', allowed_values = (
136       'auto',       # detect gettext, if not found, use included
137       'included',   # always use included gettext
138       'system',     # always use system gettext, fail if can not find
139       ) ),
140   #
141   EnumOption('spell', 'Choose spell checker to use.', 'auto',
142     allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
143   # packaging method
144   EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
145     allowed_values = ('windows', 'posix', 'macosx')),
146   #
147   BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
148   # FIXME: I do not know how pch is working. Ignore this option now.
149   BoolOption('pch', '(NA) Whether or not use pch', None),
150   # enable assertion, (config.h has ENABLE_ASSERTIOS
151   BoolOption('assertions', 'Use assertions', True),
152   # enable warning, (config.h has WITH_WARNINGS)
153   # default to False since MSVC does not have #warning
154   BoolOption('warnings', 'Use warnings', False),
155   # enable glib, (config.h has _GLIBCXX_CONCEPT_CHECKS)
156   BoolOption('concept_checks', 'Enable concept checks', True),
157   #
158   BoolOption('nls', 'Whether or not use native language support', True),
159   # FIXME: not implemented
160   BoolOption('profile', '(NA) Whether or not enable profiling', False),
161   # FIXME: not implemented
162   BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False),
163   # using x11?
164   BoolOption('X11', 'Use x11 windows system', default_with_x),
165   # use MS VC++ to build lyx
166   BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
167   #
168   PathOption('qt_dir', 'Path to qt directory', None),
169   #
170   PathOption('qt_include_path', 'Path to qt include directory', None),
171   #
172   PathOption('qt_lib_path', 'Path to qt library directory', None),
173   # build directory, will use $mode if not set
174   PathOption('build_dir', 'Build directory', None),
175   # extra include and libpath
176   PathOption('extra_inc_path', 'Extra include path', None),
177   #
178   PathOption('extra_lib_path', 'Extra library path', None),
179   #
180   PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
181   #
182   PathOption('extra_inc_path1', 'Extra include path', None),
183   #
184   PathOption('extra_lib_path1', 'Extra library path', None),
185   # rebuild only specifed, comma separated targets
186   ('rebuild', 'rebuild only specifed, comma separated targets', None),
187   # can be set to a non-existing directory
188   ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
189   # version suffix
190   ('version_suffix', 'install lyx as lyx-suffix', None),
191   # how to load options
192   ('load_option', '''load option from previous scons run. option can be
193     yes (default): load all options
194     no: do not load any option
195     opt1,opt2: load specified options
196     -opt1,opt2: load all options other than specified ones''', 'yes'),
197   #
198   ('optimization', 'optimization CCFLAGS option.', None),
199   #
200   PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
201   # log file
202   ('logfile', 'save commands (not outputs) to logfile', default_log_file),
203   # provided for backward compatibility
204   ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
205   # environment variable can be set as options.
206   ('DESTDIR', 'install to DESTDIR', None),
207   ('CC', 'replace default $CC', None),
208   ('LINK', 'replace default $LINK', None),
209   ('CPP', 'replace default $CPP', None),
210   ('CXX', 'replace default $CXX', None),
211   ('CXXCPP', 'replace default $CXXCPP', None),
212   ('CCFLAGS', 'replace default $CCFLAGS', None),
213   ('CPPFLAGS', 'replace default $CPPFLAGS', None),
214   ('LINKFLAGS', 'replace default $LINKFLAGS', None),
215 )
216
217 # copied from SCons/Options/BoolOption.py
218 # We need to use them before a boolean ARGUMENTS option is available
219 # in env as bool.
220 true_strings  = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
221 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
222
223 # whether or not use current config.h, and cached tests
224 #
225 # if fast_start=yes (default), load variables from env_cache_file
226 if (not ARGUMENTS.has_key('fast_start') or \
227   ARGUMENTS['fast_start'] in true_strings) \
228   and os.path.isfile(env_cache_file):
229   fast_start = True
230   cache_file = open(env_cache_file)
231   env_cache = cPickle.load(cache_file)
232   cache_file.close()
233   print '------------ fast_start mode --------------------'
234   print '  Use cached test results and current config.h'
235   print '  use fast_start=no to override'
236   print
237 else:
238   fast_start = False
239   env_cache = {}
240
241 # if load_option=yes (default), load saved comand line options
242 #
243 # This option can take value yes/no/opt1,opt2/-opt1,opt2
244 # and tries to be clever in choosing options to load
245 if (not ARGUMENTS.has_key('load_option') or \
246   ARGUMENTS['load_option'] not in false_strings) \
247   and os.path.isfile(env_cache_file):
248   cache_file = open(env_cache_file)
249   opt_cache = cPickle.load(cache_file)['arg_cache']
250   cache_file.close()
251   # import cached options, but we should ignore qt_dir when frontend changes
252   if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
253     and ARGUMENTS['frontend'] != opt_cache['frontend'] \
254     and opt_cache.has_key('qt_dir'):
255     opt_cache.pop('qt_dir')
256   # some options will require full rebuild
257   # these are in general things that will change src/config.h
258   for arg in ['version_suffix', 'nls', 'boost', 'spell']:
259     if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
260       ARGUMENTS[arg] != opt_cache[arg]):
261       if fast_start:
262         print "  ** fast_start is disabled because of the change of option", arg
263         print
264         fast_start = False
265   # and we do not cache some options
266   for arg in ['fast_start', 'load_option']:
267     if opt_cache.has_key(arg):
268       opt_cache.pop(arg)
269   # now, if load_option=opt1,opt2 or -opt1,opt2
270   if ARGUMENTS.has_key('load_option') and \
271     ARGUMENTS['load_option'] not in true_strings + false_strings:
272     # if -opt1,opt2 is specified, do not load these options
273     if ARGUMENTS['load_option'][0] == '-':
274       for arg in ARGUMENTS['load_option'][1:].split(','):
275         if opt_cache.has_key(arg):
276           opt_cache.pop(arg)
277     # if opt1,opt2 is specified, only load specified options
278     else:
279       args = ARGUMENTS['load_option'].split(',')
280       for arg in opt_cache.keys():
281         if arg not in args:
282           opt_cache.pop(arg)
283   # now restore options as if entered from command line
284   for key in opt_cache.keys():
285     if not ARGUMENTS.has_key(key):
286       ARGUMENTS[key] = opt_cache[key]
287       print "Restoring cached option  %s=%s" % (key, ARGUMENTS[key])
288   print
289
290 # save arguments
291 env_cache['arg_cache'] = ARGUMENTS
292
293
294 #---------------------------------------------------------
295 # Setting up environment
296 #---------------------------------------------------------
297
298 # I do not really like ENV=os.environ, but you may add it
299 # here if you experience some environment related problem
300 env = Environment(options = opts)
301
302 # set individual variables since I do not really like ENV = os.environ
303 env['ENV']['PATH'] = os.environ.get('PATH')
304 env['ENV']['HOME'] = os.environ.get('HOME')
305 # these are defined for MSVC
306 env['ENV']['LIB'] = os.environ.get('LIB')
307 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
308
309 # for simplicity, use var instead of env[var]
310 frontend = env['frontend']
311 prefix = env['prefix']
312
313 if platform_name == 'win32':
314   if env.has_key('use_vc'):
315     use_vc = env['use_vc']
316     if WhereIs('cl.exe') is None:
317       print "cl.exe is not found. Are you using the MSVC environment?"
318       Exit(2)
319   elif WhereIs('cl.exe') is not None:
320     use_vc = True
321   else:
322     use_vc = False
323 else:
324   use_vc = False
325
326 # lyx will be built to $build/build_dir so it is possible
327 # to build multiple build_dirs using the same source
328 # $mode can be debug or release
329 if env.has_key('build_dir') and env['build_dir'] is not None:
330   env['BUILDDIR'] = env['build_dir']
331 else:
332   # Determine the name of the build $mode
333   env['BUILDDIR'] = '#' + env['mode']
334
335 # all built libraries will go to build_dir/libs
336 # (This is different from the make file approach)
337 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
338 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
339
340
341 # Here is a summary of variables defined in env
342 # 1. defined options
343 # 2. undefined options with a non-None default value
344 # 3. compiler commands and flags like CCFLAGS.
345 #     MSGFMT used to process po files
346 # 4. Variables that will be used to replace variables in some_file.in
347 #     src/support/package.C.in: 
348 #       TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
349 #     lib/lyx2lyx/lyx2lyx_version.py.in
350 #       PACKAGE_VERSION
351 #     src/version.C.in
352 #       PACKAGE_VERSION, VERSION_INFO
353 #     src/frontends/xforms/lyx_xpm.h.in
354 #       XPM_H_LOCATION
355 #     src/frontends/xforms/lyx_forms.h.in
356 #       FORMS_H_LOCATION
357
358 # full path name is used to build msvs project files
359 # and to replace TOP_SRCDIR in package.C
360 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
361 # needed by src/version.C.in => src/version.C
362 env['PACKAGE_VERSION'] = package_version
363
364 # determine share_dir etc
365 packaging_method = env.get('packaging')
366 if packaging_method == 'windows':
367   share_dir = 'Resources'
368   man_dir = 'Resources/man/man1'
369   locale_dir = 'Resources/locale'
370   default_prefix = 'c:/program files/lyx'
371 else:
372   share_dir = 'share/lyx'
373   man_dir = 'man/man1'
374   locale_dir = 'share/locale'
375   default_prefix = '/usr/local/'
376
377 # install to default_prefix by default
378 # program suffix: can be yes, or a string
379 if env.has_key('version_suffix'):
380   if env['version_suffix'] in true_strings:
381     program_suffix = package_version
382   elif env['version_suffix'] in false_strings:
383     program_suffix = ''
384   else:
385     program_suffix = env['version_suffix']
386 else:
387   program_suffix = ''
388 # used by package.C.in
389 env['PROGRAM_SUFFIX'] = program_suffix
390
391 # whether or not add suffix to file and directory names
392 add_suffix = packaging_method != 'windows'
393 # LYX_DIR are different (used in package.C.in)
394 if add_suffix:
395   env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
396 else:
397   env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
398 # we need absolute path for package.C
399 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
400
401
402 #---------------------------------------------------------
403 # Setting building environment (Tools, compiler flags etc)
404 #---------------------------------------------------------
405
406 # Since Tool('mingw') will reset CCFLAGS etc, this should be
407 # done before getEnvVariable
408 if platform_name == 'win32':
409   if use_vc:
410     env.Tool('msvc')
411     env.Tool('mslink')
412   else:
413     env.Tool('mingw')
414     env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
415
416 # we differentiate between hard-coded options and default options
417 # hard-coded options are required and will always be there
418 # default options can be replaced by enviromental variables or command line options
419 CCFLAGS_required = []
420 LINKFLAGS_required = []
421 CCFLAGS_default = []
422
423 # under windows, scons is confused by .C/.c and uses gcc instead of
424 # g++. I am forcing the use of g++ here. This is expected to change
425 # after lyx renames all .C files to .cpp
426 #
427 # save the old c compiler and CCFLAGS (used by libintl)
428 C_COMPILER = env.subst('$CC')
429 C_CCFLAGS = env.subst('$CCFLAGS').split()
430 # if we use ms vc, the commands are fine (cl.exe and link.exe)
431 if use_vc:
432   # /TP treat all source code as C++
433   # C4819: The file contains a character that cannot be represented
434   #   in the current code page (number)
435   # C4996: foo was decleared deprecated
436   CCFLAGS_required.extend(['/TP', '/EHsc'])
437   CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
438 else:
439   if env.has_key('CXX') and env['CXX']:
440     env['CC'] = env.subst('$CXX')
441     env['LINK'] = env.subst('$CXX')
442   else:
443     env['CC'] = 'g++'
444     env['LINK'] = 'g++'
445
446 # for debug/release mode
447 if env.has_key('optimization') and env['optimization'] is not None:
448   # if user supplies optimization flags, use it anyway
449   CCFLAGS_required.extend(env['optimization'].split())
450   # and do not use default
451   set_default_optimization_flags = False
452 else:
453   set_default_optimization_flags = True
454
455 if env['mode'] == 'debug':
456   if use_vc:
457     CCFLAGS_required.append('/Zi')
458     LINKFLAGS_required.extend(['/debug', '/map'])
459   else:
460     CCFLAGS_required.append('-g')
461     CCFLAGS_default.append('-Wall')
462 elif env['mode'] == 'release' and set_default_optimization_flags:
463   if use_vc:
464     CCFLAGS_default.append('/O2')
465   else:
466     CCFLAGS_default.append('-O2')
467
468 # Now, set the variables as follows:
469 # 1. if command line option exists: replace default
470 # 2. then if s envronment variable exists: replace default
471 # 3. set variable to required + default
472 def setEnvVariable(env, name, required = None, default = None, split = True):
473   ''' env: environment to set variable
474       name: variable
475       required: hardcoded options
476       default: default options that can be replaced by command line or
477         environment variables
478       split: whether or not split obtained variable like '-02 -g'
479   '''
480   # first try command line argument (override environment settings)
481   if ARGUMENTS.has_key(name):
482     default = ARGUMENTS[name]
483     if split:
484       default = default.split()
485   # then use environment default
486   elif os.environ.has_key(name):
487     print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
488     default = os.environ[name]
489     if split:
490       default = default.split()
491   # set variable
492   if required is not None:
493     env[name] = required
494   if default is not None:
495     if env.has_key(name):
496       env[name] += default
497     else:
498       env[name] = default
499
500 setEnvVariable(env, 'DESTDIR', split=False)
501 setEnvVariable(env, 'CC')
502 setEnvVariable(env, 'LINK')
503 setEnvVariable(env, 'CPP')
504 setEnvVariable(env, 'CXX')
505 setEnvVariable(env, 'CXXCPP')
506 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
507 setEnvVariable(env, 'CXXFLAGS')
508 setEnvVariable(env, 'CPPFLAGS')
509 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
510
511 # if DESTDIR is not set...
512 if env.has_key('dest_dir'):
513   print "This option is obsolete. Please use DESTDIR instead."
514   env['DESTDIR'] = env['dest_dir']
515 dest_dir = env.get('DESTDIR', prefix)
516
517 #---------------------------------------------------------
518 # Frontend related variables (QTDIR etc)
519 #---------------------------------------------------------
520
521 if env.has_key('qt_dir') and env['qt_dir']:
522   env['QTDIR'] = env['qt_dir']
523   # add path to the qt tools
524   env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
525   # set environment so that moc etc can be found even if its path is not set properly
526   env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
527 else:
528   env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
529
530 if env.has_key('qt_lib_path') and env['qt_lib_path']:
531   qt_lib_path = env.subst('$qt_lib_path')
532 else:
533   qt_lib_path = env.subst('$QTDIR/lib')
534 env.AppendUnique(LIBPATH = [qt_lib_path])
535 # qt4 seems to be using pkg_config
536 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
537
538 if env.has_key('qt_inc_path') and env['qt_inc_path']:
539   qt_inc_path = env['qt_inc_path']
540 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
541   qt_inc_path = '$QTDIR/include'
542 # this is the path for cygwin.
543 elif os.path.isdir('/usr/include/' + frontend):
544   qt_inc_path = '/usr/include/$frontend'
545 else: 
546   print "Qt include directory not found. Please specify it using qt_inc_path"
547   Exit(1)
548 # Note that this CPPPATH is for testing only
549 # it will be removed before calling SConscript
550 env['CPPPATH'] = [qt_inc_path]
551
552 #
553 # extra_inc_path and extra_lib_path
554 #
555 extra_inc_paths = []
556 if env.has_key('extra_inc_path') and env['extra_inc_path']:
557   extra_inc_paths.append(env['extra_inc_path'])
558 if env.has_key('extra_lib_path') and env['extra_lib_path']:
559   env.AppendUnique(LIBPATH = [env['extra_lib_path']])
560 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
561   extra_inc_paths.append(env['extra_inc_path1'])
562 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
563   env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
564 if env.has_key('extra_bin_path') and env['extra_bin_path']:
565   # maybe only one of them is needed
566   os.environ['PATH'] += os.pathsep + env['extra_bin_path']
567   env['ENV']['PATH'] += os.pathsep + env['extra_bin_path']
568 # extra_inc_paths will be used later by intlenv etc
569 env.AppendUnique(CPPPATH = extra_inc_paths)
570
571
572 #----------------------------------------------------------
573 # Autoconf business
574 #----------------------------------------------------------
575
576 conf = Configure(env,
577   custom_tests = {
578     'CheckPkgConfig' : utils.checkPkgConfig,
579     'CheckPackage' : utils.checkPackage,
580     'CheckMkdirOneArg' : utils.checkMkdirOneArg,
581     'CheckSelectArgType' : utils.checkSelectArgType,
582     'CheckBoostLibraries' : utils.checkBoostLibraries,
583     'CheckCommand' : utils.checkCommand,
584     'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
585     'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
586   }
587 )
588
589 # pkg-config? (if not, we use hard-coded options)
590 if not fast_start:
591   if conf.CheckPkgConfig('0.15.0'):
592     env['HAS_PKG_CONFIG'] = True
593   else:
594     print 'pkg-config >= 0.1.50 is not found'
595     env['HAS_PKG_CONFIG'] = False
596   env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
597 else:
598   env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
599
600 # zlib? This is required. (fast_start assumes the existance of zlib)
601 if not fast_start:
602   if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
603     or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
604     print 'Did not find zdll.lib or zlib.h, exiting!'
605     Exit(1)
606
607 # qt libraries?
608 if not fast_start:
609   #
610   # qt3 does not use pkg_config
611   if frontend in ['qt2', 'qt3']:
612     if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
613       print 'Did not find qt libraries, exiting!'
614       Exit(1)
615   elif frontend == 'qt4':
616     succ = False
617     # first: try pkg_config
618     if env['HAS_PKG_CONFIG']:
619       succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
620       env['QT4_PKG_CONFIG'] = succ
621     # second: try to link to it
622     if not succ:
623       # FIXME: under linux, I can test the following perfectly
624       # However, under windows, lib names need to passed as libXXX4.a ...
625       succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
626         conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
627     # third: try to look up the path
628     if not succ:
629       succ = True
630       for lib in ['QtCore', 'QtGui']:
631         # windows version has something like QtGui4 ...
632         if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
633           os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
634           succ = False
635           break
636     # still can not find it
637     if succ:
638       print "Qt4 libraries are found."
639     else:
640       print 'Did not find qt libraries, exiting!'
641       Exit(1)
642
643 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
644 if use_vc:
645   # glob file xxx.dll.manifest (msvc 2003 may not have it)
646   manifests = glob.glob(os.path.join(qt_lib_path, '*.dll.manifest'))
647   if manifests != []:
648     env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifests[0]]
649
650 # check socket libs
651 if not fast_start:
652   socket_libs = []
653   if conf.CheckLib('socket'):
654     socket_libs.append('socket')
655   # nsl is the network services library and provides a
656   # transport-level interface to networking services.
657   if conf.CheckLib('nsl'):
658     socket_libs.append('nsl')
659   env_cache['SOCKET_LIBS'] = socket_libs
660 else:
661   socket_libs = env_cache['SOCKET_LIBS']
662
663 # check available boost libs (since lyx1.4 does not use iostream)
664 boost_libs = []
665 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
666   if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
667     boost_libs.append(lib)
668
669 if not fast_start:
670   # check boost libraries
671   boost_opt = ARGUMENTS.get('boost', 'auto')
672   # check for system boost
673   paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
674   boost_libraries = []
675   boost_libpath = None
676   # here I assume that all libraries are in the same directory
677   for lib in boost_libs:
678     if boost_opt == 'included':
679       boost_libraries.append('included_boost_%s' % lib)
680       env['INCLUDED_BOOST'] = True
681     elif boost_opt == 'auto':
682       res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
683       # if not found
684       if res[0] == '':
685         boost_libraries.append('included_boost_%s' % lib)
686         env['INCLUDED_BOOST'] = True
687       else:
688         boost_libraries.append(res[1])
689         env['INCLUDED_BOOST'] = False
690         boost_libpath = res[0]
691     elif boost_opt == 'system':
692       res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
693       if res[0] == '':
694         print "Can not find system boost libraries"
695         print "Please supply a path through extra_lib_path and try again."
696         print "Or use boost=included to use included boost libraries."
697         Exit(2)
698       else:
699         boost_libraries.append(res[1])
700         env.AppendUnique(LIBPATH = [res[0]])
701         boost_libpath = res[0]
702   env_cache['BOOST_LIBRARIES'] = boost_libraries
703   env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
704   env_cache['BOOST_LIBPATH'] = boost_libpath
705 else:
706   boost_libraries = env_cache['BOOST_LIBRARIES']
707   if env_cache['BOOST_LIBPATH'] is not None:
708     env.AppendUnique(LIBPATH = [env_cache['BOOST_LIBPATH']])
709   env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
710
711
712 env['ENABLE_NLS'] = env['nls']
713
714 if not fast_start:
715   if not env['ENABLE_NLS']:
716     intl_libs = []
717     included_gettext = False
718   else:
719     # check gettext libraries
720     gettext_opt = ARGUMENTS.get('gettext', 'auto')
721     # check for system gettext
722     succ = False
723     if gettext_opt in ['auto', 'system']:
724       if conf.CheckLib('intl'):
725         included_gettext = False
726         intl_libs = ['intl']
727         succ = True
728       else: # no found
729         if gettext_opt == 'system':
730           print "Can not find system gettext library"
731           print "Please supply a path through extra_lib_path and try again."
732           print "Or use gettext=included to use included gettext libraries."
733           Exit(2)
734     # now, auto and succ = false, or gettext=included
735     if not succ:
736       # we do not need to set LIBPATH now.
737       included_gettext = True
738       intl_libs = ['included_intl']
739   env_cache['INCLUDED_GETTEXT'] = included_gettext
740   env_cache['INTL_LIBS'] = intl_libs
741 else:
742   intl_libs = env_cache['INTL_LIBS']
743   included_gettext = env_cache['INCLUDED_GETTEXT']
744
745 #
746 # check for msgfmt command
747 if not fast_start:
748   env['MSGFMT'] = conf.CheckCommand('msgfmt')
749   env_cache['MSGFMT'] = env['MSGFMT']
750 else:
751   env['MSGFMT'] = env_cache['MSGFMT']
752
753
754 #----------------------------------------------------------
755 # Generating config.h
756 #----------------------------------------------------------
757 if not fast_start:
758   print "Generating src/config.h..."
759
760   # AIKSAURUS_H_LOCATION
761   if (conf.CheckCXXHeader("Aiksaurus.h")):
762     aik_location = '<Aiksaurus.h>'
763   elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
764     aik_location = '<Aiksaurus/Aiksaurus.h>'
765   else:
766     aik_location = ''
767
768   # determine headers to use
769   spell_opt = ARGUMENTS.get('spell', 'auto')
770   env['USE_ASPELL'] = False
771   env['USE_PSPELL'] = False
772   env['USE_ISPELL'] = False
773   if spell_opt in ['auto', 'aspell'] and conf.CheckLib('aspell'):
774     spell_engine = 'USE_ASPELL'
775   elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
776     spell_engine = 'USE_PSPELL'
777   elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
778     spell_engine = 'USE_ISPELL'
779   else:
780     spell_engine = None
781
782   if spell_engine is not None:
783     env[spell_engine] = True
784   else:
785     if spell_opt == 'auto':
786       print "Warning: Can not locate any spell checker"
787     elif spell_opt != 'no':
788       print "Warning: Can not locate specified spell checker:", spell_opt
789       Exit(1)
790   
791   # check arg types of select function
792   (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
793
794   #
795   # create config.h
796   result = utils.createConfigFile(conf,
797     config_file = os.path.join(top_src_dir, 'src', 'config.h'),
798     config_pre = '''/* src/config.h.  Generated by SCons.  */
799
800 /* -*- C++ -*- */
801 /*
802  * \file config.h
803  * This file is part of LyX, the document processor.
804  * Licence details can be found in the file COPYING.
805  *
806  * This is the compilation configuration file for LyX.
807  * It was generated by scon.
808  * You might want to change some of the defaults if something goes wrong
809  * during the compilation.
810  */
811
812 #ifndef _CONFIG_H
813 #define _CONFIG_H
814 ''',
815     headers = [
816       ('io.h', 'HAVE_IO_H', 'c'),
817       ('limits.h', 'HAVE_LIMITS_H', 'c'),
818       ('locale.h', 'HAVE_LOCALE_H', 'c'),
819       ('locale', 'HAVE_LOCALE', 'cxx'),
820       ('process.h', 'HAVE_PROCESS_H', 'c'),
821       ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
822       ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
823       ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
824       ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
825       ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
826       ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
827       ('unistd.h', 'HAVE_UNISTD_H', 'c'),
828       ('utime.h', 'HAVE_UTIME_H', 'c'),
829       ('direct.h', 'HAVE_DIRECT_H', 'c'),
830       ('istream', 'HAVE_ISTREAM', 'cxx'),
831       ('ostream', 'HAVE_OSTREAM', 'cxx'),
832       ('ios', 'HAVE_IOS', 'cxx'),
833     ],
834     functions = [
835       ('open', 'HAVE_OPEN', None),
836       ('close', 'HAVE_CLOSE', None),
837       ('popen', 'HAVE_POPEN', None),
838       ('pclose', 'HAVE_PCLOSE', None),
839       ('_open', 'HAVE__OPEN', None),
840       ('_close', 'HAVE__CLOSE', None),
841       ('_popen', 'HAVE__POPEN', None),
842       ('_pclose', 'HAVE__PCLOSE', None),
843       ('getpid', 'HAVE_GETPID', None),
844       ('_getpid', 'HAVE__GETPID', None),
845       ('mkdir', 'HAVE_MKDIR', None),
846       ('_mkdir', 'HAVE__MKDIR', None),
847       ('mktemp', 'HAVE_MKTEMP', None),
848       ('mkstemp', 'HAVE_MKSTEMP', None),
849       ('strerror', 'HAVE_STRERROR', None),
850       ('count', 'HAVE_STD_COUNT', '''
851   #include <algorithm>
852   int count()
853   {
854     char a[] = "hello";
855     return std::count(a, a+5, 'l');
856   }
857   '''),
858       ('getcwd', 'HAVE_GETCWD', None),
859       ('setenv', 'HAVE_SETENV', None),
860       ('putenv', 'HAVE_PUTENV', None),
861       ('fcntl', 'HAVE_FCNTL', None),
862     ],
863     types = [
864       ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
865         '#include <streambuf>\n#include <istream>')
866     ],
867     libs = [
868       ('gdi32', 'HAVE_LIBGDI32'),
869       (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
870       (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
871     ],
872     custom_tests = [
873       (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
874         'HAVE_PID_T',
875         'Define is sys/types.h does not have pid_t',
876         '',
877         '#define pid_t int',
878       ),
879       (conf.CheckCXXGlobalCstd(),
880         'CXX_GLOBAL_CSTD',
881         'Define if your C++ compiler puts C library functions in the global namespace'
882       ),
883       (conf.CheckMkdirOneArg(),
884         'MKDIR_TAKES_ONE_ARG',
885         'Define if mkdir takes only one argument.'
886       ),
887       (conf.CheckLC_MESSAGES(),
888         'HAVE_LC_MESSAGES',
889         'Define if your <locale.h> file defines LC_MESSAGES.'
890       ),
891       (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
892       (env.has_key('assertions') and env['assertions'],
893         'ENABLE_ASSERTIONS',
894         'Define if you want assertions to be enabled in the code'
895       ),
896       (env.has_key('nls') and env['nls'],
897         'ENABLE_NLS',
898         "Define to 1 if translation of program messages to the user's native anguage is requested.",
899       ),
900       (env.has_key('warnings') and env['warnings'],
901         'WITH_WARNINGS',
902         'Define this if you want to see the warning directives put here and there by the developpers to get attention'
903       ),
904       (env.has_key('concept_checks') and env['concept_checks'],
905         '_GLIBCXX_CONCEPT_CHECKS',
906         'libstdc++ concept checking'
907       ),
908       (os.name != 'nt', 'BOOST_POSIZ',
909         'Indicates to boost which API to use (posix or windows).'
910       ),
911       (spell_engine is not None, spell_engine,
912         'Spell engine to use'
913       ),
914     ],
915     extra_items = [
916       ('#define PACKAGE "%s%s"' % (package, program_suffix),
917         'Name of package'),
918       ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
919         'Define to the address where bug reports for this package should be sent.'),
920       ('#define PACKAGE_NAME "%s"' % package_name,
921         'Define to the full name of this package.'),
922       ('#define PACKAGE_STRING "%s"' % package_string,
923         'Define to the full name and version of this package.'),
924       ('#define PACKAGE_TARNAME "%s"' % package_tarname,
925         'Define to the one symbol short name of this package.'),
926       ('#define PACKAGE_VERSION "%s"' % package_version,
927         'Define to the version of this package.'),
928       ('#define BOOST_ALL_NO_LIB 1',
929         'disable automatic linking of boost libraries.'),
930       ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
931         'Packaging method'),
932       ('#define AIKSAURUS_H_LOCATION ' + aik_location,
933         'Aiksaurus include file'),
934       ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
935         "Define to the type of arg 1 for `select'."),
936       ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
937         "Define to the type of arg 2, 3, 4 for `select'."),
938       ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
939         "Define to the type of arg 5 for `select'."),
940     ],
941     config_post = '''/************************************************************
942  ** You should not need to change anything beyond this point */
943
944 #ifndef HAVE_STRERROR
945 #if defined(__cplusplus)
946 extern "C"
947 #endif
948 char * strerror(int n);
949 #endif
950
951 #ifdef HAVE_MKSTEMP
952 #ifndef HAVE_DECL_MKSTEMP
953 #if defined(__cplusplus)
954 extern "C"
955 #endif
956 int mkstemp(char*);
957 #endif
958 #endif
959
960 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
961 #  define USE_BOOST_FORMAT 1
962 #else
963 #  define USE_BOOST_FORMAT 0
964 #endif
965
966 #define BOOST_USER_CONFIG <config.h>
967
968 #if !defined(ENABLE_ASSERTIONS)
969 #  define BOOST_DISABLE_ASSERTS 1
970 #endif
971 #define BOOST_ENABLE_ASSERT_HANDLER 1
972
973 #define BOOST_DISABLE_THREADS 1
974 #define BOOST_NO_WREGEX 1
975 #define BOOST_NO_WSTRING 1
976
977 #ifdef __CYGWIN__
978 #  define BOOST_POSIX 1
979 #endif
980
981 #if defined(HAVE_NEWAPIS_H)
982 #  define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
983 #endif
984
985 #endif
986 '''
987   )
988
989   # these keys are needed in env
990   for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
991     'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
992     'ICONV_LIB', 'AIKSAURUS_LIB']:
993     # USE_ASPELL etc does not go through result
994     if result.has_key(key):
995       env[key] = result[key]
996     env_cache[key] = env[key]
997 else:
998   #
999   # this comes as a big surprise, without this line
1000   # (doing nothing obvious), adding fast_start=yes
1001   # to a build with fast_start=no will result in a rebuild
1002   # Note that the exact header file to check does not matter
1003   conf.CheckCHeader('io.h')
1004   # only a few variables need to be rescanned
1005   for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1006     'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1007     'ICONV_LIB', 'AIKSAURUS_LIB']:
1008     env[key] = env_cache[key]
1009
1010 #
1011 # Finish auto-configuration
1012 env = conf.Finish()
1013
1014 #----------------------------------------------------------
1015 # Now set up our build process accordingly
1016 #----------------------------------------------------------
1017
1018 #
1019 # QT_LIB
1020 #
1021 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1022 # in their respective directory and specialized env.
1023 try:
1024   if frontend in ['qt2', 'qt3']:
1025     # note: env.Tool('qt') my set QT_LIB to qt
1026     qt_libs = ['qt-mt']
1027     frontend_libs = ['qt-mt']
1028   elif frontend == 'qt4':
1029     if platform_name == "win32":
1030       qt_libs = ['QtCore4', 'QtGui4']
1031     else:
1032       qt_libs = ['QtCore', 'QtGui']
1033     frontend_libs = qt_libs
1034 except:
1035   print "Can not locate qt tools"
1036   print "What I get is "
1037   print "  QTDIR: ", env['QTDIR']
1038
1039
1040 if platform_name in ['win32', 'cygwin']:
1041   # the final link step needs stdc++ to succeed under mingw
1042   # FIXME: shouldn't g++ automatically link to stdc++?
1043   if use_vc:
1044     system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1045   else:
1046     system_libs = ['shlwapi', 'stdc++', 'z']
1047 elif platform_name == 'cygwin' and env['X11']:
1048   system_libs = ['GL',  'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1049     'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1050     'pthread', 'z']
1051 else:
1052   system_libs = ['z']
1053
1054 libs = [
1055   ('HAVE_ICONV', env['ICONV_LIB']),
1056   ('HAVE_LIBGDI32', 'gdi32'),
1057   ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1058   ('USE_ASPELL', 'aspell'),
1059   ('USE_ISPELL', 'ispell'),
1060   ('USE_PSPELL', 'pspell'),
1061 ]
1062
1063 for lib in libs:
1064   if env[lib[0]]:
1065     system_libs.append(lib[1])
1066
1067 #
1068 # Build parameters CPPPATH etc
1069 #
1070 if env['X11']:
1071   env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1072
1073 #
1074 # boost is always in, src is needed for config.h
1075 #
1076 # QT_INC_PATH is not needed for *every* source file
1077 env['CPPPATH'].remove(qt_inc_path)
1078 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$TOP_SRCDIR/src']
1079
1080 #
1081 # Customized builders
1082 #
1083 # install customized builders
1084 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
1085
1086 #
1087 # A Link script for cygwin see
1088 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1089 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1090 # for details
1091 #
1092 if platform_name == 'cygwin':
1093   ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1094   ld_script = utils.installCygwinLDScript(ld_script_path)
1095   env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1096     '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1097
1098 #
1099 # Report results
1100 #
1101 # fill in the version info
1102 env['VERSION_INFO'] = '''Configuration
1103   Host type:                      %s
1104   Special build flags:            %s
1105   C   Compiler:                   %s
1106   C   Compiler flags:             %s %s
1107   C++ Compiler:                   %s
1108   C++ Compiler LyX flags:         %s
1109   C++ Compiler flags:             %s %s
1110   Linker flags:                   %s
1111   Linker user flags:              %s
1112 Build info:
1113   Builing directory:              %s
1114   Local library directory:        %s
1115   Libraries paths:                %s
1116   Boost libraries:                %s
1117   Frontend libraries:             %s
1118   System libraries:               %s
1119   include search path:            %s
1120 Frontend:
1121   Frontend:                       %s
1122   Packaging:                      %s
1123   LyX dir:                        %s
1124   LyX files dir:                  %s
1125 ''' % (platform_name,
1126   env.subst('$CCFLAGS'), env.subst('$CC'),
1127   env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1128   env.subst('$CXX'), env.subst('$CXXFLAGS'),
1129   env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1130   env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1131   env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1132   str(env['LIBPATH']), str(boost_libraries),
1133   str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1134   frontend, packaging_method,
1135   prefix, env['LYX_DIR'])
1136
1137 if frontend in ['qt2', 'qt3', 'qt4']:
1138   env['VERSION_INFO'] += '''  include dir:                    %s
1139   library dir:                    %s
1140   X11:                            %s
1141 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1142
1143 if not fast_start:
1144   print env['VERSION_INFO']
1145
1146 #
1147 # Mingw command line may be too short for our link usage,
1148 # Here we use a trick from scons wiki
1149 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1150 #
1151 # I also would like to add logging (commands only) capacity to the
1152 # spawn system.
1153 logfile = env.get('logfile', default_log_file)
1154 if logfile != '' or platform_name == 'win32':
1155   import time
1156   utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1157     info = '''# This is a log of commands used by scons to build lyx
1158 # Time: %s
1159 # Command: %s
1160 # Info: %s
1161 ''' % (time.asctime(), ' '.join(sys.argv),
1162   env['VERSION_INFO'].replace('\n','\n# ')) )
1163
1164
1165 # Cleanup stuff
1166 #
1167 # -h will print out help info
1168 Help(opts.GenerateHelpText(env))
1169
1170
1171 #----------------------------------------------------------
1172 # Start building
1173 #----------------------------------------------------------
1174 # this has been the source of problems on some platforms...
1175 # I find that I need to supply it with full path name
1176 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1177 # this usage needs further investigation.
1178 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1179
1180 print "Building all targets recursively"
1181
1182 if env.has_key('rebuild'):
1183   rebuild_targets = env['rebuild'].split(',')
1184 else:
1185   rebuild_targets = None
1186
1187 def libExists(libname):
1188   ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1189   return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1190
1191 targets = BUILD_TARGETS
1192 # msvc need to pass full target name, so I have to look for path/lyx etc
1193 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1194   or 'install' in targets or 'all' in targets
1195 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1196 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1197 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1198 build_mathed = build_lyx or 'mathed' in targets
1199 build_insets = build_lyx or 'insets' in targets
1200 build_frontends = build_lyx or 'frontends' in targets
1201 build_graphics = build_lyx or 'graphics' in targets
1202 build_controllers = build_lyx or 'controllers' in targets
1203 build_client = True in ['client' in x for x in targets] \
1204   or 'install' in targets or 'all' in targets
1205 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1206   or 'install' in targets or 'all' in targets
1207 build_lyxbase = build_lyx or 'lyxbase' in targets
1208 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1209 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1210 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1211 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1212 build_msvs_projects = use_vc and 'msvs_projects' in targets
1213
1214
1215 # now, if rebuild_targets is specified, do not rebuild some targets
1216 rebuild_targets = rebuild_targets
1217 if rebuild_targets:
1218   def ifBuildLib(name, libname, old_value):
1219     # explicitly asked to rebuild
1220     if name in rebuild_targets:
1221       return True
1222     # else if not rebuild, and if the library already exists
1223     elif libExists(libname):
1224       return False
1225     # do not change the original value
1226     else:
1227       return old_value
1228   build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1229   build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1230   build_support = ifBuildLib('support', 'support', build_support)
1231   build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1232   build_insets = ifBuildLib('insets', 'insets', build_insets)
1233   build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1234   build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1235   build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1236   build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1237   build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1238   build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1239   build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1240
1241 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1242 if build_qt2:
1243   frontend = 'qt2'
1244 elif build_qt3:
1245   frontend = 'qt3'
1246 elif build_qt4:
1247   frontend = 'qt4'
1248
1249
1250 if build_boost:
1251   #
1252   # boost libraries
1253   #
1254   # special builddir
1255   env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1256
1257   boostenv = env.Copy()
1258   #
1259   boost_config_h = os.path.join(top_src_dir, 'boost', 'libs', 'config.h')
1260   if not os.path.isfile(boost_config_h) or not fast_start:
1261     #
1262     print "Creating boost/config.h..."
1263     #
1264     # start another configuration session.
1265     conf = Configure(boostenv, 
1266       custom_tests = {'CheckMkdirOneArg' : utils.checkMkdirOneArg},
1267     )      
1268     #
1269     # create config.h
1270     result = utils.createConfigFile(conf,
1271       config_file = boost_config_h,
1272       config_pre = '''/* boost/libs/config.h.  Generated by SCons.  */
1273
1274 /* -*- C++ -*- */
1275 /*
1276  * \file config.h
1277  * This file is part of LyX, the document processor.
1278  * Licence details can be found in the file COPYING.
1279  *
1280  * This is the compilation configuration file for LyX.
1281  * It was generated by scon.
1282  * You might want to change some of the defaults if something goes wrong
1283  * during the compilation.
1284  */
1285
1286 #ifndef _CONFIG_H
1287 #define _CONFIG_H
1288 ''',
1289       headers = [
1290         ('io.h', 'HAVE_IO_H', 'c'),
1291         ('limits.h', 'HAVE_LIMITS_H', 'c'),
1292         ('locale.h', 'HAVE_LOCALE_H', 'c'),
1293         ('locale', 'HAVE_LOCALE', 'cxx'),
1294         ('process.h', 'HAVE_PROCESS_H', 'c'),
1295         ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
1296         ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
1297         ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
1298         ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
1299         ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
1300         ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
1301         ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1302         ('utime.h', 'HAVE_UTIME_H', 'c'),
1303         ('direct.h', 'HAVE_DIRECT_H', 'c'),
1304         ('istream', 'HAVE_ISTREAM', 'cxx'),
1305         ('ostream', 'HAVE_OSTREAM', 'cxx'),
1306         ('ios', 'HAVE_IOS', 'cxx'),
1307       ],
1308       functions = [
1309         ('open', 'HAVE_OPEN', None),
1310         ('close', 'HAVE_CLOSE', None),
1311         ('popen', 'HAVE_POPEN', None),
1312         ('pclose', 'HAVE_PCLOSE', None),
1313         ('_open', 'HAVE__OPEN', None),
1314         ('_close', 'HAVE__CLOSE', None),
1315         ('_popen', 'HAVE__POPEN', None),
1316         ('_pclose', 'HAVE__PCLOSE', None),
1317         ('getpid', 'HAVE_GETPID', None),
1318         ('_getpid', 'HAVE__GETPID', None),
1319         ('mkdir', 'HAVE_MKDIR', None),
1320         ('_mkdir', 'HAVE__MKDIR', None),
1321         ('mktemp', 'HAVE_MKTEMP', None),
1322         ('mkstemp', 'HAVE_MKSTEMP', None),
1323         ('strerror', 'HAVE_STRERROR', None),
1324         ('getcwd', 'HAVE_GETCWD', None),
1325         ('setenv', 'HAVE_SETENV', None),
1326         ('putenv', 'HAVE_PUTENV', None),
1327         ('fcntl', 'HAVE_FCNTL', None),
1328       ],
1329       custom_tests = [
1330         (conf.CheckMkdirOneArg(),
1331           'MKDIR_TAKES_ONE_ARG',
1332           'Define if mkdir takes only one argument.'
1333         ),
1334         (env.has_key('assertions') and env['assertions'],
1335           'ENABLE_ASSERTIONS',
1336           'Define if you want assertions to be enabled in the code'
1337         ),
1338         (env.has_key('warnings') and env['warnings'],
1339           'WITH_WARNINGS',
1340           'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1341         ),
1342         (env.has_key('concept_checks') and env['concept_checks'],
1343           '_GLIBCXX_CONCEPT_CHECKS',
1344           'libstdc++ concept checking'
1345         ),
1346         (os.name != 'nt', 'BOOST_POSIZ',
1347           'Indicates to boost which API to use (posix or windows).'
1348         ),
1349       ],
1350       extra_items = [
1351         ('#define BOOST_ALL_NO_LIB 1',
1352           'disable automatic linking of boost libraries.'),
1353       ],
1354       config_post = '''
1355
1356 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
1357 #  define USE_BOOST_FORMAT 1
1358 #else
1359 #  define USE_BOOST_FORMAT 0
1360 #endif
1361
1362 #define BOOST_USER_CONFIG <config.h>
1363
1364 #if !defined(ENABLE_ASSERTIONS)
1365 #  define BOOST_DISABLE_ASSERTS 1
1366 #endif
1367 #define BOOST_ENABLE_ASSERT_HANDLER 1
1368
1369 #define BOOST_DISABLE_THREADS 1
1370 #define BOOST_NO_WREGEX 1
1371 #define BOOST_NO_WSTRING 1
1372
1373 #ifdef __CYGWIN__
1374 #  define BOOST_POSIX 1
1375 #endif
1376
1377 #endif
1378 '''
1379     )
1380     conf.Finish()
1381   # 
1382   # boost use its own config.h
1383   boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$TOP_SRCDIR/boost/libs'] + extra_inc_paths
1384   boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1385
1386   for lib in boost_libs:
1387     print 'Processing files in boost/libs/%s/src...' % lib
1388     boostlib = boostenv.StaticLibrary(
1389       target = '$LOCALLIBPATH/included_boost_%s' % lib,
1390       source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1391         pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1392     )
1393     Alias('boost', boostlib)
1394
1395
1396 if build_intl:
1397   #
1398   # intl
1399   #
1400   intlenv = env.Copy()
1401   #
1402   intl_config_h = os.path.join(top_src_dir, 'intl', 'config.h')
1403   if not os.path.isfile(intl_config_h) or not fast_start:
1404     #
1405     print "Creating intl/config.h..."
1406     #
1407     # start another configuration session.
1408     conf = Configure(intlenv,
1409       custom_tests = {
1410         'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
1411         'CheckIconvConst' : utils.checkIconvConst,
1412       }
1413     )
1414     # create config.h
1415     result = utils.createConfigFile(conf,
1416       config_file = intl_config_h,
1417       config_pre = '''/* intl/config.h.  Generated by SCons.  */
1418
1419 /* -*- C++ -*- */
1420 /*
1421  * \file config.h
1422  * This file is part of LyX, the document processor.
1423  * Licence details can be found in the file COPYING.
1424  *
1425  * This is the compilation configuration file for LyX.
1426  * It was generated by scon.
1427  * You might want to change some of the defaults if something goes wrong
1428  * during the compilation.
1429  */
1430
1431 #ifndef _CONFIG_H
1432 #define _CONFIG_H
1433 ''',
1434       headers = [
1435         ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1436         ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1437         ('string.h', 'HAVE_STRING_H', 'c'),
1438         ('strings.h', 'HAVE_STRINGS_H', 'c'),
1439         ('argz.h', 'HAVE_ARGZ_H', 'c'),
1440         ('limits.h', 'HAVE_LIMITS_H', 'c'),
1441         ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1442         ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1443         ('stdint.h', 'HAVE_STDINT_H', 'c'),
1444         ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1445       ],
1446       functions = [
1447         ('getcwd', 'HAVE_GETCWD', None),
1448         ('stpcpy', 'HAVE_STPCPY', None),
1449         ('strcasecmp', 'HAVE_STRCASECMP', None),
1450         ('strdup', 'HAVE_STRDUP', None),
1451         ('strtoul', 'HAVE_STRTOUL', None),
1452         ('alloca', 'HAVE_ALLOCA', None),
1453         ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1454         ('mempcpy', 'HAVE_MEMPCPY', None),
1455         ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1456         ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1457         ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1458         ('setlocale', 'HAVE_SETLOCALE', None),
1459         ('tsearch', 'HAVE_TSEARCH', None),
1460         ('getegid', 'HAVE_GETEGID', None),
1461         ('getgid', 'HAVE_GETGID', None),
1462         ('getuid', 'HAVE_GETUID', None),
1463         ('wcslen', 'HAVE_WCSLEN', None),
1464         ('asprintf', 'HAVE_ASPRINTF', None),
1465         ('wprintf', 'HAVE_WPRINTF', None),
1466         ('snprintf', 'HAVE_SNPRINTF', None),
1467         ('printf', 'HAVE_POSIX_PRINTF', None),
1468         ('fcntl', 'HAVE_FCNTL', None),
1469       ],
1470       types = [
1471         ('intmax_t', 'HAVE_INTMAX_T', None),
1472         ('long double', 'HAVE_LONG_DOUBLE', None),
1473         ('long long', 'HAVE_LONG_LONG', None),
1474         ('wchar_t', 'HAVE_WCHAR_T', None),
1475         ('wint_t', 'HAVE_WINT_T', None),
1476         ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1477         ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1478       ],
1479       libs = [
1480         (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1481         ('c', 'HAVE_LIBC'),
1482       ],
1483       custom_tests = [
1484         (conf.CheckLC_MESSAGES(),
1485           'HAVE_LC_MESSAGES',
1486           'Define if your <locale.h> file defines LC_MESSAGES.'
1487         ),
1488         (conf.CheckIconvConst(),
1489           'ICONV_CONST',
1490           'Define as const if the declaration of iconv() needs const.',
1491           '#define ICONV_CONST',
1492           '#define ICONV_CONST const',
1493         ),
1494         (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1495          conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1496           'HAVE_INTMAX_T',
1497           "Define to 1 if you have the `intmax_t' type."
1498         ),
1499         (env.has_key('nls') and env['nls'],
1500           'ENABLE_NLS',
1501           "Define to 1 if translation of program messages to the user's native anguage is requested.",
1502         ),
1503       ],
1504       config_post = '#endif'   
1505     )
1506     conf.Finish()
1507     # these keys are needed in env
1508     for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1509       'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1510       # USE_ASPELL etc does not go through result
1511       if result.has_key(key):
1512         env[key] = result[key]
1513       env_cache[key] = env[key]
1514   else:
1515     # only a few variables need to be rescanned
1516     for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1517       'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1518       env[key] = env_cache[key]
1519
1520   print "Processing files in intl..."
1521
1522   env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1523
1524   # we need the original C compiler for these files
1525   intlenv['CC'] = C_COMPILER
1526   intlenv['CCFLAGS'] = C_CCFLAGS
1527   if use_vc:
1528     intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1529   # intl does not use global config.h
1530   intlenv['CPPPATH'] = ['intl'] + extra_inc_paths
1531
1532   intlenv.Append(CCFLAGS = [
1533     r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1534     r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1535     r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1536     '-DIN_LIBINTL',
1537     '-DENABLE_RELOCATABLE=1',
1538     '-DIN_LIBRARY',
1539     r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1540     '-DNO_XMALLOC',
1541     '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1542     '-Drelocate=libintl_relocate',
1543     '-DDEPENDS_ON_LIBICONV=1',
1544     '-DHAVE_CONFIG_H'
1545     ]
1546   )
1547
1548   # libgnuintl.h.in => libintl.h
1549   env.substFile('$TOP_SRCDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1550   env.Command('$TOP_SRCDIR/intl/libgnuintl.h', '$TOP_SRCDIR/intl/libintl.h',
1551       [Copy('$TARGET', '$SOURCE')])
1552
1553   intl = intlenv.StaticLibrary(
1554     target = '$LOCALLIBPATH/included_intl',
1555     LIBS = ['c'],
1556     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1557       exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1558       build_dir = '$BUILDDIR/intl')
1559   )
1560   Alias('intl', intl)
1561
1562
1563 #
1564 # Now, src code under src/
1565 #
1566 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1567
1568
1569 if build_support:
1570   #
1571   # src/support
1572   #
1573   print "Processing files in src/support..."
1574
1575   env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1576
1577   support = env.StaticLibrary(
1578     target = '$LOCALLIBPATH/support',
1579     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1580       exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1581       include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1582   )
1583   Alias('support', support)
1584
1585
1586 if build_mathed:
1587   #
1588   # src/mathed
1589   #
1590   print "Processing files in src/mathed..."
1591
1592   mathed = env.StaticLibrary(
1593     target = '$LOCALLIBPATH/mathed',
1594     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'), pattern = lyx_ext,
1595       exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1596       build_dir = '$BUILDDIR/common/mathed')
1597   )
1598   Alias('mathed', mathed)
1599
1600
1601 if build_insets:
1602   #
1603   # src/insets
1604   #
1605   print "Processing files in src/insets..."
1606
1607   insets = env.StaticLibrary(
1608     target = '$LOCALLIBPATH/insets',
1609     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'), pattern = lyx_ext,
1610       exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1611   )
1612   Alias('insets', insets)
1613
1614
1615 if build_frontends:
1616   #
1617   # src/frontends
1618   #
1619   print "Processing files in src/frontends..."
1620
1621   frontends = env.StaticLibrary(
1622     target = '$LOCALLIBPATH/frontends',
1623     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1624       build_dir = '$BUILDDIR/common/frontends')
1625   )
1626   Alias('frontends', frontends)
1627
1628
1629 if build_graphics:
1630   #
1631   # src/graphics
1632   #
1633   print "Processing files in src/graphics..."
1634
1635   graphics = env.StaticLibrary(
1636     target = '$LOCALLIBPATH/graphics',
1637     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1638       build_dir = '$BUILDDIR/common/graphics')
1639   )
1640   Alias('graphics', graphics)
1641
1642
1643 if build_controllers:
1644   #
1645   # src/frontends/controllers
1646   #
1647   print "Processing files in src/frontends/controllers..."
1648
1649   controllers = env.StaticLibrary(
1650     target = '$LOCALLIBPATH/controllers',
1651     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1652       build_dir = '$BUILDDIR/common/frontends/controllers')
1653   )
1654   Alias('controllers', controllers)
1655
1656
1657 #
1658 # src/frontend/qt2/3/4
1659 #
1660 if build_qt2 or build_qt3 or build_qt4:
1661   env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1662
1663
1664 if build_qt2:
1665   print "Processing files in src/frontends/qt2..."
1666
1667   qt2env = env.Copy()
1668   # disable auto scan to speed up non build time
1669   qt2env['QT_AUTOSCAN'] = 0
1670   qt2env['QT_MOCHPREFIX'] = ''
1671
1672   # load qt2 tools
1673   qt2env.Tool('qt')
1674
1675   qt2env.AppendUnique(CPPPATH = [
1676     '$BUILDDIR/common',
1677     '$BUILDDIR/common/images',
1678     '$BUILDDIR/common/frontends',
1679     '$BUILDDIR/common/frontends/qt2',
1680     '$BUILDDIR/common/frontends/controllers',
1681     qt_inc_path]
1682   )
1683
1684   qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1685     BulletsModule.C
1686     emptytable.C
1687     FileDialog_private.C
1688     floatplacement.C
1689     iconpalette.C
1690     lengthcombo.C
1691     panelstack.C
1692     QAboutDialog.C
1693     QBibitemDialog.C
1694     QBibtexDialog.C
1695     QBoxDialog.C
1696     QBranchDialog.C
1697     QBrowseBox.C
1698     QChangesDialog.C
1699     QCharacterDialog.C
1700     QCitationDialog.C
1701     QCommandBuffer.C
1702     QCommandEdit.C
1703     QContentPane.C
1704     QDelimiterDialog.C
1705     QDocumentDialog.C
1706     QErrorListDialog.C
1707     QERTDialog.C
1708     QExternalDialog.C
1709     QFloatDialog.C
1710     QGraphicsDialog.C
1711     QIncludeDialog.C
1712     QIndexDialog.C
1713     QLogDialog.C
1714     QLPopupMenu.C
1715     QLPrintDialog.C
1716     QMathDialog.C
1717     QMathMatrixDialog.C
1718     QNoteDialog.C
1719     QParagraphDialog.C
1720     QPrefsDialog.C
1721     QRefDialog.C
1722     QSearchDialog.C
1723     QSendtoDialog.C
1724     qsetborder.C
1725     QShowFileDialog.C
1726     QSpellcheckerDialog.C
1727     QDialogView.C
1728     QTabularCreateDialog.C
1729     QTabularDialog.C
1730     QTexinfoDialog.C
1731     QThesaurusDialog.C
1732     QTocDialog.C
1733     qttableview.C
1734     QtView.C
1735     QURLDialog.C
1736     QVSpaceDialog.C
1737     QWrapDialog.C
1738     QLToolbar.C
1739     socket_callback.C
1740     validators.C
1741   ''')]
1742
1743   # manually moc and uic files for better performance
1744   qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1745
1746   qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1747      utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1748
1749   qt2_uiced_cc_files = []
1750   for x in qt2_uiced_files:
1751     qt2_uiced_cc_files.extend(x[1:])
1752
1753   qt2 = qt2env.StaticLibrary(
1754     target = '$LOCALLIBPATH/qt2',
1755     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1756       build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1757   )
1758   Alias('qt2', qt2)
1759
1760
1761 if build_qt3:
1762   print "Processing files in src/frontends/qt3..."
1763
1764   qt3env = env.Copy()
1765   # disable auto scan to speed up non build time
1766   qt3env['QT_AUTOSCAN'] = 0
1767   qt3env['QT_MOCHPREFIX'] = ''
1768
1769   # load qt3 tools
1770   qt3env.Tool('qt')
1771
1772   qt3env.AppendUnique(CPPPATH = [
1773     '$BUILDDIR/common',
1774     '$BUILDDIR/common/images',
1775     '$BUILDDIR/common/frontends',
1776     '$BUILDDIR/common/frontends/qt3',
1777     '$BUILDDIR/common/frontends/controllers',
1778     qt_inc_path]
1779   )
1780
1781   qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1782     BulletsModule.C
1783     emptytable.C
1784     FileDialog_private.C
1785     floatplacement.C
1786     iconpalette.C
1787     lengthcombo.C
1788     panelstack.C
1789     QAboutDialog.C
1790     QBibitemDialog.C
1791     QBibtexDialog.C
1792     QBoxDialog.C
1793     QBranchDialog.C
1794     QBrowseBox.C
1795     QChangesDialog.C
1796     QCharacterDialog.C
1797     QCitationDialog.C
1798     QCommandBuffer.C
1799     QCommandEdit.C
1800     QContentPane.C
1801     QDelimiterDialog.C
1802     QDocumentDialog.C
1803     QErrorListDialog.C
1804     QERTDialog.C
1805     QExternalDialog.C
1806     QFloatDialog.C
1807     QGraphicsDialog.C
1808     QIncludeDialog.C
1809     QIndexDialog.C
1810     QLogDialog.C
1811     QViewSourceDialog.C
1812     QLPopupMenu.C
1813     QLPrintDialog.C
1814     QMathDialog.C
1815     QMathMatrixDialog.C
1816     QNoteDialog.C
1817     QParagraphDialog.C
1818     QPrefsDialog.C
1819     QRefDialog.C
1820     QSearchDialog.C
1821     QSendtoDialog.C
1822     qsetborder.C
1823     QShowFileDialog.C
1824     QSpellcheckerDialog.C
1825     QDialogView.C
1826     QTabularCreateDialog.C
1827     QTabularDialog.C
1828     QTexinfoDialog.C
1829     QThesaurusDialog.C
1830     QTocDialog.C
1831     qttableview.C
1832     QtView.C
1833     QURLDialog.C
1834     QVSpaceDialog.C
1835     QWrapDialog.C
1836     QLToolbar.C
1837     socket_callback.C
1838     validators.C
1839   ''')]
1840
1841   # manually moc and uic files for better performance
1842   qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1843
1844   qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1845      utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1846
1847   qt3_uiced_cc_files = []
1848   for x in qt3_uiced_files:
1849     qt3_uiced_cc_files.extend(x[1:])
1850
1851   qt3 = qt3env.StaticLibrary(
1852     target = '$LOCALLIBPATH/qt3',
1853     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1854       build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1855   )
1856   Alias('qt3', qt3)
1857
1858
1859 if build_qt4:
1860   print "Processing files in src/frontends/qt4..."
1861
1862   qt4env = env.Copy()
1863   qt4env['QT_AUTOSCAN'] = 0
1864
1865   # local qt4 toolset from
1866   # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1867   #
1868   # NOTE: I have to patch qt4.py since it does not automatically
1869   # process .C file!!! (add to cxx_suffixes )
1870   #
1871   qt4env.Tool('qt4', [scons_dir])
1872   qt4env.EnableQt4Modules(qt_libs, debug = False)
1873
1874   qt4env.AppendUnique(CPPPATH = [
1875     '$BUILDDIR/common',
1876     '$BUILDDIR/common/images',
1877     '$BUILDDIR/common/frontends',
1878     '$BUILDDIR/common/frontends/qt4',
1879     '$BUILDDIR/common/frontends/controllers',
1880     qt_inc_path
1881     ]
1882   )
1883
1884   # FIXME: replace by something from pkg_config
1885   qt4env.Append(CCFLAGS = [
1886     '-DHAVE_CONFIG_H',
1887     '-DQT_CLEAN_NAMESPACE',
1888     '-DQT_GENUINE_STR',
1889     '-DQT_NO_STL',
1890     '-DQT3_SUPPORT',
1891     ]
1892   )
1893
1894
1895   qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1896     BulletsModule.C
1897     emptytable.C
1898     FileDialog_private.C
1899     floatplacement.C
1900     iconpalette.C
1901     lengthcombo.C
1902     InsertTableWidget.C
1903     panelstack.C
1904     QAboutDialog.C
1905     QBibitemDialog.C
1906     QBibtexDialog.C
1907     QBoxDialog.C
1908     QBranchDialog.C
1909     QBranches.C
1910     QChangesDialog.C
1911     QCharacterDialog.C
1912     QCitationDialog.C
1913     QCommandBuffer.C
1914     QCommandEdit.C
1915     QDelimiterDialog.C
1916     QDocumentDialog.C
1917     QErrorListDialog.C
1918     QERTDialog.C
1919     QExternalDialog.C
1920     QFloatDialog.C
1921     QGraphicsDialog.C
1922     QIncludeDialog.C
1923     QIndexDialog.C
1924     QLAction.C
1925     QLogDialog.C
1926     QViewSourceDialog.C
1927     QViewSource.C
1928     QLMenubar.C
1929     QLPopupMenu.C
1930     QLPrintDialog.C
1931     QMathDialog.C
1932     QMathMatrixDialog.C
1933     QNoteDialog.C
1934     QParagraphDialog.C
1935     QPrefsDialog.C
1936     QRefDialog.C
1937     QSearchDialog.C
1938     QSendtoDialog.C
1939     qsetborder.C
1940     QShowFileDialog.C
1941     QSpellcheckerDialog.C
1942     QDialogView.C
1943     QTabularCreateDialog.C
1944     QTabularDialog.C
1945     QTexinfoDialog.C
1946     QThesaurusDialog.C
1947     TocModel.C
1948     QTocDialog.C
1949     QtView.C
1950     QURLDialog.C
1951     QVSpaceDialog.C
1952     QWorkArea.C
1953     QWrapDialog.C
1954     QLToolbar.C
1955     socket_callback.C
1956     validators.C
1957   ''') ]
1958
1959   #
1960   # Compile resources
1961   #
1962   resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1963     utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1964       build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1965
1966   #
1967   # moc qt4_moc_files, the moced files are included in the original files
1968   #
1969   qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1970
1971   qt4 = qt4env.StaticLibrary(
1972     target = '$LOCALLIBPATH/qt4',
1973     LIBS = qt_libs,
1974     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1975       exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1976   )
1977   Alias('qt4', qt4)
1978
1979
1980 if build_client:
1981   #
1982   # src/client
1983   #
1984   env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1985
1986   print "Processing files in src/client..."
1987
1988   if env['HAVE_FCNTL']:
1989     client = env.Program(
1990       target = '$BUILDDIR/common/client/lyxclient',
1991       LIBS = ['support'] + intl_libs + system_libs +
1992         socket_libs + boost_libraries,
1993       source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1994         build_dir = '$BUILDDIR/common/client')
1995     )
1996     Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1997       client, [Copy('$TARGET', '$SOURCE')]))
1998   else:
1999     client = None
2000   Alias('client', client)
2001
2002
2003 if build_tex2lyx:
2004   #
2005   # tex2lyx
2006   #
2007   print "Processing files in src/tex2lyx..."
2008
2009   tex2lyx_env = env.Copy()
2010   # the order is important here.
2011   tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2012   tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2013
2014   for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2015     'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2016     env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2017       [Copy('$TARGET', '$SOURCE')])
2018
2019   tex2lyx = tex2lyx_env.Program(
2020     target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2021     LIBS = ['support'] + boost_libraries + system_libs,
2022     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2023       include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2024         'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2025       build_dir = '$BUILDDIR/common/tex2lyx')
2026   )
2027   Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2028     tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2029   Alias('tex2lyx', tex2lyx)
2030
2031
2032 if build_lyxbase:
2033   #
2034   # src/
2035   #
2036   print "Processing files in src..."
2037
2038   env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2039
2040   lyx_post_source = Split('''
2041     tabular.C
2042     dimension.C
2043     PrinterParams.C
2044     box.C
2045     Thesaurus.C
2046     SpellBase.C
2047   ''')
2048
2049   if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2050     lyx_post_source.append('aspell.C')
2051   elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2052     lyx_post_source.append('pspell.C')
2053   elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2054     lyx_post_source.append('ispell.C')
2055
2056   # msvc requires at least one source file with main()
2057   # so I exclude main.C from lyxbase
2058   lyxbase_pre = env.StaticLibrary(
2059     target = '$LOCALLIBPATH/lyxbase_pre',
2060     source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2061       exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C', 
2062         'ispell.C', 'Variables.C', 'Sectioning.C'],
2063       include = ['version.C'], build_dir = '$BUILDDIR/common')
2064   )
2065   lyxbase_post = env.StaticLibrary(
2066     target = '$LOCALLIBPATH/lyxbase_post',
2067     source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2068   )
2069   Alias('lyxbase', lyxbase_pre)
2070   Alias('lyxbase', lyxbase_post)
2071
2072
2073 if build_lyx:
2074   #
2075   # Build lyx with given frontend
2076   #
2077   lyx = env.Program(
2078     target = '$BUILDDIR/$frontend/lyx',
2079     source = ['$BUILDDIR/common/main.C'],
2080     LIBS = [
2081       'lyxbase_pre',
2082       'mathed',
2083       'insets',
2084       'frontends',
2085       frontend,
2086       'controllers',
2087       'graphics',
2088       'support',
2089       'lyxbase_post',
2090       ] +
2091       boost_libraries +
2092       frontend_libs +
2093       intl_libs +
2094       socket_libs +
2095       system_libs
2096   )
2097   # [/path/to/lyx.ext] => lyx-qt3.ext
2098   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2099   Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2100     [Copy('$TARGET', '$SOURCE')]))
2101   Alias('lyx', lyx)
2102
2103
2104 if build_msvs_projects:
2105   def build_project(target, dir, full_target = None,
2106     src_pattern = lyx_ext, include = [], resource = None, rebuild = True):
2107     ''' build mavs project files
2108       target:      alias (correspond to directory name)
2109       dir:         source directory or directories (a list)
2110       full_target: full path/filename of the target
2111       src_pattern: glob pattern
2112       include:     files to include into source
2113       resource:    directory or directories with resource (.ui) files
2114       rebuild:     whether or not only rebuild this target
2115
2116     For non-debug-able targets like static libraries, target (alias) is
2117     enough to build the target. For executable targets, msvs need to know
2118     the full path to start debug them.
2119     '''
2120     if resource is not None:
2121       res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2122         build_dir = env.subst('$TOP_SRCDIR/'+resource))
2123     else:
2124       res = []
2125     if rebuild:
2126       cmds = 'faststart=yes rebuild='+target
2127     else:
2128       cmds = 'faststart=yes'
2129     if type(dir) == type([]):
2130       src = []
2131       inc = []
2132       for d in dir:
2133         src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2134           pattern = src_pattern, include = include,
2135           build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2136         inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2137           pattern = '*.h',
2138           build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2139     else:
2140       src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2141         pattern = src_pattern, include = include,
2142         build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2143       inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2144         pattern = '*.h',
2145         build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2146     if full_target is None:
2147       build_target = target
2148     else:
2149       build_target = full_target
2150     # project
2151     proj = env.MSVSProject(
2152       target = target + env['MSVSPROJECTSUFFIX'],
2153       srcs = src,
2154       incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2155       localincs = inc,
2156       resources = res,
2157       buildtarget = build_target,
2158       cmdargs = cmds,
2159       variant = 'Debug'
2160     )
2161     Alias('msvs_projects', proj)
2162   #
2163   build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2164     src_pattern = '*.cpp')
2165   #
2166   build_project('intl', 'intl', src_pattern = '*.c')
2167   #
2168   build_project('support', 'src/support', include=['package.C.in'])
2169   #
2170   build_project('mathed', 'src/mathed')
2171   #
2172   build_project('insets', 'src/insets')
2173   #
2174   build_project('frontends', 'src/frontends')
2175   #
2176   build_project('graphics', 'src/graphics')
2177   #
2178   build_project('controllers', 'src/frontends/controllers')
2179   #
2180   build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2181   #
2182   build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2183   #
2184   build_project('client', 'src/client', rebuild=False,
2185     full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2186   #
2187   build_project('tex2lyx', 'src/tex2lyx', rebuild=False,
2188     full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2189   #
2190   build_project('lyxbase', 'src')
2191   #
2192   if frontend == 'qt3':
2193     build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2194       'src/frontends', 'src/graphics', 'src/frontends/controllers',
2195       'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2196       full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2197   else:
2198     build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2199       'src/frontends', 'src/graphics', 'src/frontends/controllers',
2200       'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2201       full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2202
2203
2204 if build_po:
2205   #
2206   # po/
2207   #
2208   print 'Processing files in po...'
2209
2210   import glob
2211   # handle po files
2212   #
2213   # files to translate
2214   transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2215   # possibly *only* handle these languages
2216   languages = None
2217   if env.has_key('languages'):
2218     languages = env.make_list(env['lanauges'])
2219   # use defulat msgfmt
2220   if not env['MSGFMT']:
2221     print 'msgfmt does not exist. Can not process po files'
2222   else:
2223     # create a builder
2224     env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2225     #
2226     gmo_files = []
2227     for f in transfiles:
2228       # get filename
2229       fname = os.path.split(f)[1]
2230       # country code
2231       country = fname.split('.')[0]
2232       #
2233       if not languages or country in languages:
2234         gmo_files.extend(env.Transfiles(f))
2235
2236
2237 if 'install' in targets:
2238   # if dest_dir is different from prefix.
2239   if env.has_key('exec_prefix'):
2240     bin_dest_dir = env['exec_prefix']
2241   else:
2242     bin_dest_dir = os.path.join(dest_dir, 'bin')
2243   if add_suffix:
2244     share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2245   else:
2246     share_dest_dir = os.path.join(dest_dir, share_dir)
2247   man_dest_dir = os.path.join(dest_dir, man_dir)
2248   locale_dest_dir = os.path.join(dest_dir, locale_dir)
2249   # create the directory if needed
2250   if not os.path.isdir(dest_dir):
2251     try:
2252       os.makedirs(dest_dir)
2253     except:
2254       pass
2255     if not os.path.isdir(dest_dir):
2256       print 'Can not create directory', dest_dir
2257       Exit(3)
2258   #
2259   import glob
2260   #
2261   # do not install these files
2262   exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2263     'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
2264
2265   def install(dest, src):
2266     ''' recusive installation of src to dest '''
2267     # separate file and directory
2268     files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2269     dirs = filter(os.path.isdir, src)
2270     # install file
2271     env.Install(dest, files)
2272     # install directory
2273     ins_dir = [dest]
2274     for dir in dirs:
2275       ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2276         glob.glob(os.path.join(dir, '*'))) )
2277     return ins_dir
2278   #
2279   # executables (some of them may be none)
2280   #
2281   if add_suffix:
2282     version_suffix = program_suffix
2283   else:
2284     version_suffix = ''
2285   #
2286   # install lyx
2287   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2288   target = os.path.join(bin_dest_dir, target_name)
2289   env.InstallAs(target, lyx)
2290   Alias('install', target)
2291   # install lyx as lyx-qt3
2292   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2293   target = os.path.join(bin_dest_dir, target_name)
2294   env.InstallAs(target, lyx)
2295   Alias('install', target)
2296   #
2297   # install tex2lyx
2298   target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2299   target = os.path.join(bin_dest_dir, target_name)
2300   env.InstallAs(target, tex2lyx)
2301   Alias('install', target)
2302   #
2303   # install lyxclient, may not exist
2304   if client != None:
2305     target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2306     target = os.path.join(bin_dest_dir, target_name)
2307     env.InstallAs(target, client)
2308     Alias('install', target)
2309   #
2310   # share/lyx
2311   dirs = install(share_dest_dir,
2312     [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2313      'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2314      'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2315      'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc',  'ui']]
2316   )
2317   env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2318     '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2319   Alias('install', dirs)
2320   # man
2321   env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2322     env.subst('$TOP_SRCDIR/lyx.man'))
2323   env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2324     env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2325   env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2326     env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2327   Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2328     x in ['lyx', 'tex2lyx', 'lyxclient']])
2329   # locale files?
2330   # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2331   for gmo in gmo_files:
2332     lan = os.path.split(str(gmo))[1].split('.')[0]
2333     dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2334     env.InstallAs(dest_file, gmo)
2335     Alias('install', dest_file)
2336
2337
2338 Default('lyx')
2339 Alias('all', ['lyx', 'client', 'tex2lyx'])
2340
2341
2342 # save environment settings (for fast_start option)
2343 cache_file = open(env_cache_file, 'w')
2344 cPickle.dump(env_cache, cache_file)
2345 cache_file.close()