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