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