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