]> git.lyx.org Git - lyx.git/blob - development/scons/SConstruct
get rid of QT3_SUPPORT
[lyx.git] / development / scons / SConstruct
1 # vi:filetype=python:expandtab:tabstop=4:shiftwidth=4
2 #
3 # file SConstruct
4 #
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7 #
8 # \author Bo Peng
9 # Full author contact details are available in file CREDITS.
10 #
11 # This is a scons based building system for lyx, please refer
12 # to INSTALL.scons for detailed instructions.
13 #
14
15 import os, sys, copy, cPickle, glob
16
17 # scons_utils.py defines a few utility function
18 sys.path.append('config')
19 import scons_utils as utils
20 # 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         # windows lib name is qt-mt3
684         if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \
685             and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'):
686             print 'Did not find qt libraries, exiting!'
687             Exit(1)
688     elif frontend == 'qt4':
689         succ = False
690         # first: try pkg_config
691         if env['HAS_PKG_CONFIG']:
692             succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
693             # FIXME: use pkg_config information?
694             #env['QT4_PKG_CONFIG'] = succ
695         # second: try to link to it
696         if not succ:
697             # Under linux, I can test the following perfectly
698             # Under windows, lib names need to passed as libXXX4.a ...
699             succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
700                 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
701         # third: try to look up the path
702         if not succ:
703             succ = True
704             for lib in ['QtCore', 'QtGui']:
705                 # windows version has something like QtGui4 ...
706                 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
707                     os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
708                     succ = False
709                     break
710         # still can not find it
711         if succ:
712             print "Qt4 libraries are found."
713         else:
714             print 'Did not find qt libraries, exiting!'
715             Exit(1)
716
717 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
718 if use_vc:
719     if frontend == 'qt3':
720         manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest')
721     elif frontend == 'qt4':
722         if mode == 'debug':
723             manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
724         else:
725             manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
726     if os.path.isfile(manifest):
727         env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
728
729 # check socket libs
730 if not fast_start:
731     socket_libs = []
732     if conf.CheckLib('socket'):
733         socket_libs.append('socket')
734     # nsl is the network services library and provides a
735     # transport-level interface to networking services.
736     if conf.CheckLib('nsl'):
737         socket_libs.append('nsl')
738     env_cache['SOCKET_LIBS'] = socket_libs
739 else:
740     socket_libs = env_cache['SOCKET_LIBS']
741
742 # check available boost libs (since lyx1.4 does not use iostream)
743 boost_libs = []
744 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
745     if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
746         boost_libs.append(lib)
747
748 if not fast_start:
749     # check boost libraries
750     boost_opt = ARGUMENTS.get('boost', 'auto')
751     # check for system boost
752     lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
753     inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
754     # default to $BUILDDIR/libs (use None since this path will be added anyway)
755     boost_libpath = None
756     # here I assume that all libraries are in the same directory
757     if boost_opt == 'included':
758         boost_libraries = ['included_boost_%s' % x for x in boost_libs]
759         included_boost = True
760         env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
761     elif boost_opt == 'auto':
762         res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
763         # if not found, use local boost
764         if res[0] is None:
765             boost_libraries = ['included_boost_%s' % x for x in boost_libs]
766             included_boost = True
767             env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
768         else:
769             included_boost = False
770             (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
771     elif boost_opt == 'system':
772         res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
773         if res[0] is None:
774             print "Can not find system boost libraries with version %s " % boost_version
775             print "Please supply a path through extra_lib_path and try again."
776             print "Or use boost=included to use included boost libraries."
777             Exit(2)
778         else:
779             included_boost = False
780             (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
781     env_cache['BOOST_LIBRARIES'] = boost_libraries
782     env_cache['INCLUDED_BOOST'] = included_boost
783     env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
784     env_cache['BOOST_LIBPATH'] = boost_libpath
785 else:
786     boost_libraries = env_cache['BOOST_LIBRARIES']
787     included_boost = env_cache['INCLUDED_BOOST']
788     env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
789     boost_libpath = env_cache['BOOST_LIBPATH']
790
791 if boost_libpath is not None:
792     env.AppendUnique(LIBPATH = [boost_libpath])
793
794
795 env['ENABLE_NLS'] = env['nls']
796
797 if not fast_start:
798     if not env['ENABLE_NLS']:
799         intl_libs = []
800         included_gettext = False
801     else:
802         # check gettext libraries
803         gettext_opt = ARGUMENTS.get('gettext', 'auto')
804         # check for system gettext
805         succ = False
806         if gettext_opt in ['auto', 'system']:
807             if conf.CheckLib('intl'):
808                 included_gettext = False
809                 intl_libs = ['intl']
810                 succ = True
811             else: # no found
812                 if gettext_opt == 'system':
813                     print "Can not find system gettext library"
814                     print "Please supply a path through extra_lib_path and try again."
815                     print "Or use gettext=included to use included gettext libraries."
816                     Exit(2)
817         # now, auto and succ = false, or gettext=included
818         if not succ:
819             # we do not need to set LIBPATH now.
820             included_gettext = True
821             intl_libs = ['included_intl']
822     env_cache['INCLUDED_GETTEXT'] = included_gettext
823     env_cache['INTL_LIBS'] = intl_libs
824 else:
825     included_gettext = env_cache['INCLUDED_GETTEXT']
826     intl_libs = env_cache['INTL_LIBS']
827
828 #
829 # check for msgfmt command
830 if not fast_start:
831     env['MSGFMT'] = conf.CheckCommand('msgfmt')
832     env_cache['MSGFMT'] = env['MSGFMT']
833 else:
834     env['MSGFMT'] = env_cache['MSGFMT']
835
836 # check uic and moc commands for qt frontends
837 if not fast_start:
838     if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
839         or conf.CheckCommand('moc') == None):
840         print 'uic or moc command is not found for frontend', frontend
841         Exit(1)
842
843 #
844 # Customized builders
845 #
846 # install customized builders
847 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
848
849
850 #----------------------------------------------------------
851 # Generating config.h
852 #----------------------------------------------------------
853 aspell_lib = 'aspell'
854 # assume that we use aspell, aspelld compiled for msvc
855 if platform_name == 'win32' and mode == 'debug' and use_vc:
856     aspell_lib = 'aspelld'
857
858 # check the existence of config.h
859 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
860 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
861 if not fast_start or not os.path.isfile(boost_config_h) \
862     or not os.path.isfile(config_h):
863     #
864     print "Creating %s..." % boost_config_h
865     #
866     utils.createConfigFile(conf,
867         config_file = boost_config_h,
868         config_pre = '''/* boost/config.h.  Generated by SCons.  */
869
870 /* -*- C++ -*- */
871 /*
872 * \file config.h
873 * This file is part of LyX, the document processor.
874 * Licence details can be found in the file COPYING.
875 *
876 * This is the compilation configuration file for LyX.
877 * It was generated by scon.
878 * You might want to change some of the defaults if something goes wrong
879 * during the compilation.
880 */
881
882 #ifndef _BOOST_CONFIG_H
883 #define _BOOST_CONFIG_H
884 ''',
885         headers = [
886             ('ostream', 'HAVE_OSTREAM', 'cxx'),
887             ('locale', 'HAVE_LOCALE', 'cxx'),
888             ('sstream', 'HAVE_SSTREAM', 'cxx'),
889             #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
890         ],
891         custom_tests = [
892             (env.has_key('assertions') and env['assertions'],
893                 'ENABLE_ASSERTIONS',
894                 'Define if you want assertions to be enabled in the code'
895             ),
896         ],
897         config_post = '''
898
899 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
900 #  define USE_BOOST_FORMAT 1
901 #else
902 #  define USE_BOOST_FORMAT 0
903 #endif
904
905 #if !defined(ENABLE_ASSERTIONS)
906 #  define BOOST_DISABLE_ASSERTS 1
907 #endif
908 #define BOOST_ENABLE_ASSERT_HANDLER 1
909
910 #define BOOST_DISABLE_THREADS 1
911 #define BOOST_NO_WSTRING 1
912
913 #ifdef __CYGWIN__
914 #  define BOOST_POSIX 1
915 #endif
916
917 #define BOOST_ALL_NO_LIB 1
918
919 #if defined(HAVE_NEWAPIS_H)
920 #  define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
921 #endif
922
923 #endif
924 '''
925     )
926     #
927     print "\nGenerating %s..." % config_h
928
929     # AIKSAURUS_H_LOCATION
930     if (conf.CheckCXXHeader("Aiksaurus.h")):
931         aik_location = '<Aiksaurus.h>'
932     elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
933         aik_location = '<Aiksaurus/Aiksaurus.h>'
934     else:
935         aik_location = ''
936
937     # determine headers to use
938     spell_opt = ARGUMENTS.get('spell', 'auto')
939     env['USE_ASPELL'] = False
940     env['USE_PSPELL'] = False
941     env['USE_ISPELL'] = False
942     if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
943         spell_engine = 'USE_ASPELL'
944     elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
945         spell_engine = 'USE_PSPELL'
946     elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
947         spell_engine = 'USE_ISPELL'
948     else:
949         spell_engine = None
950
951     if spell_engine is not None:
952         env[spell_engine] = True
953     else:
954         if spell_opt == 'auto':
955             print "Warning: Can not locate any spell checker"
956         elif spell_opt != 'no':
957             print "Warning: Can not locate specified spell checker:", spell_opt
958             Exit(1)
959
960     # check arg types of select function
961     (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
962
963     #
964     # create config.h
965     result = utils.createConfigFile(conf,
966         config_file = config_h,
967         config_pre = '''/* config.h.  Generated by SCons.  */
968
969 /* -*- C++ -*- */
970 /*
971 * \file config.h
972 * This file is part of LyX, the document processor.
973 * Licence details can be found in the file COPYING.
974 *
975 * This is the compilation configuration file for LyX.
976 * It was generated by scon.
977 * You might want to change some of the defaults if something goes wrong
978 * during the compilation.
979 */
980
981 #ifndef _CONFIG_H
982 #define _CONFIG_H
983 ''',
984         headers = [
985             ('io.h', 'HAVE_IO_H', 'c'),
986             ('limits.h', 'HAVE_LIMITS_H', 'c'),
987             ('locale.h', 'HAVE_LOCALE_H', 'c'),
988             ('process.h', 'HAVE_PROCESS_H', 'c'),
989             ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
990             ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
991             ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
992             ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
993             ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
994             ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
995             ('unistd.h', 'HAVE_UNISTD_H', 'c'),
996             ('utime.h', 'HAVE_UTIME_H', 'c'),
997             ('direct.h', 'HAVE_DIRECT_H', 'c'),
998             ('istream', 'HAVE_ISTREAM', 'cxx'),
999             ('ios', 'HAVE_IOS', 'cxx'),
1000         ],
1001         functions = [
1002             ('open', 'HAVE_OPEN', None),
1003             ('close', 'HAVE_CLOSE', None),
1004             ('popen', 'HAVE_POPEN', None),
1005             ('pclose', 'HAVE_PCLOSE', None),
1006             ('_open', 'HAVE__OPEN', None),
1007             ('_close', 'HAVE__CLOSE', None),
1008             ('_popen', 'HAVE__POPEN', None),
1009             ('_pclose', 'HAVE__PCLOSE', None),
1010             ('getpid', 'HAVE_GETPID', None),
1011             ('_getpid', 'HAVE__GETPID', None),
1012             ('mkdir', 'HAVE_MKDIR', None),
1013             ('_mkdir', 'HAVE__MKDIR', None),
1014             ('mktemp', 'HAVE_MKTEMP', None),
1015             ('mkstemp', 'HAVE_MKSTEMP', None),
1016             ('strerror', 'HAVE_STRERROR', None),
1017             ('count', 'HAVE_STD_COUNT', '''
1018 #include <algorithm>
1019 int count()
1020 {
1021     char a[] = "hello";
1022     return std::count(a, a+5, 'l');
1023 }
1024 '''),
1025             ('getcwd', 'HAVE_GETCWD', None),
1026             ('setenv', 'HAVE_SETENV', None),
1027             ('putenv', 'HAVE_PUTENV', None),
1028             ('fcntl', 'HAVE_FCNTL', None),
1029         ],
1030         types = [
1031             ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1032                 '#include <streambuf>\n#include <istream>')
1033         ],
1034         libs = [
1035             ('gdi32', 'HAVE_LIBGDI32'),
1036             (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1037         ],
1038         custom_tests = [
1039             (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1040                 'HAVE_PID_T',
1041                 'Define is sys/types.h does not have pid_t',
1042                 '',
1043                 '#define pid_t int',
1044             ),
1045             (conf.CheckCXXGlobalCstd(),
1046                 'CXX_GLOBAL_CSTD',
1047                 'Define if your C++ compiler puts C library functions in the global namespace'
1048             ),
1049             (conf.CheckMkdirOneArg(),
1050                 'MKDIR_TAKES_ONE_ARG',
1051                 'Define if mkdir takes only one argument.'
1052             ),
1053             (conf.CheckIconvConst(),
1054                 'ICONV_CONST',
1055                 'Define as const if the declaration of iconv() needs const.',
1056                 '#define ICONV_CONST const',
1057                 '#define ICONV_CONST',
1058             ),
1059             (conf.CheckLC_MESSAGES(),
1060                 'HAVE_LC_MESSAGES',
1061                 'Define if your <locale.h> file defines LC_MESSAGES.'
1062             ),
1063             (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1064             (env['nls'],
1065                 'ENABLE_NLS',
1066                 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1067             ),
1068             (env['nls'] and not included_gettext,
1069                 'HAVE_GETTEXT',
1070                 'Define to 1 if using system gettext library'
1071             ),
1072             (env.has_key('warnings') and env['warnings'],
1073                 'WITH_WARNINGS',
1074                 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1075             ),
1076             (env.has_key('concept_checks') and env['concept_checks'],
1077                 '_GLIBCXX_CONCEPT_CHECKS',
1078                 'libstdc++ concept checking'
1079             ),
1080             (env.has_key('stdlib_debug') and env['stdlib_debug'],
1081                 '_GLIBCXX_DEBUG',
1082                 'libstdc++ debug mode'
1083             ),
1084             (env.has_key('stdlib_debug') and env['stdlib_debug'],
1085                 '_GLIBCXX_DEBUG_PEDANTIC',
1086                 'libstdc++ pedantic debug mode'
1087             ),
1088             (os.name != 'nt', 'BOOST_POSIX',
1089                 'Indicates to boost which API to use (posix or windows).'
1090             ),
1091             (spell_engine is not None, spell_engine,
1092                 'Spell engine to use'
1093             ),
1094         ],
1095         extra_items = [
1096             ('#define PACKAGE "%s%s"' % (package, program_suffix),
1097                 'Name of package'),
1098             ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1099                 'Define to the address where bug reports for this package should be sent.'),
1100             ('#define PACKAGE_NAME "%s"' % package_name,
1101                 'Define to the full name of this package.'),
1102             ('#define PACKAGE_STRING "%s"' % package_string,
1103                 'Define to the full name and version of this package.'),
1104             ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1105                 'Define to the one symbol short name of this package.'),
1106             ('#define PACKAGE_VERSION "%s"' % package_version,
1107                 'Define to the version of this package.'),
1108             ('#define BOOST_ALL_NO_LIB 1',
1109                 'disable automatic linking of boost libraries.'),
1110             ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1111                 'Packaging method'),
1112             ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1113                 'Aiksaurus include file'),
1114             ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1115                 "Define to the type of arg 1 for `select'."),
1116             ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1117                 "Define to the type of arg 2, 3, 4 for `select'."),
1118             ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1119                 "Define to the type of arg 5 for `select'."),
1120         ],
1121         config_post = '''/************************************************************
1122 ** You should not need to change anything beyond this point */
1123
1124 #ifndef HAVE_STRERROR
1125 #if defined(__cplusplus)
1126 extern "C"
1127 #endif
1128 char * strerror(int n);
1129 #endif
1130
1131 #ifdef HAVE_MKSTEMP
1132 #ifndef HAVE_DECL_MKSTEMP
1133 #if defined(__cplusplus)
1134 extern "C"
1135 #endif
1136 int mkstemp(char*);
1137 #endif
1138 #endif
1139
1140 #include <../boost/config.h>
1141
1142 #endif
1143 '''
1144     )
1145
1146     # these keys are needed in env
1147     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1148         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1149         # USE_ASPELL etc does not go through result
1150         if result.has_key(key):
1151             env[key] = result[key]
1152         env_cache[key] = env[key]
1153
1154     #
1155     # if nls=yes and gettext=included, create intl/config.h
1156     # intl/libintl.h etc
1157     #
1158     intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1159     if env['nls'] and included_gettext:
1160         #
1161         print "Creating %s..." % intl_config_h
1162         #
1163         # create intl/config.h
1164         result = utils.createConfigFile(conf,
1165             config_file = intl_config_h,
1166             config_pre = '''/* intl/config.h.  Generated by SCons.  */
1167
1168 /* -*- C++ -*- */
1169 /*
1170 * \file config.h
1171 * This file is part of LyX, the document processor.
1172 * Licence details can be found in the file COPYING.
1173 *
1174 * This is the compilation configuration file for LyX.
1175 * It was generated by scon.
1176 * You might want to change some of the defaults if something goes wrong
1177 * during the compilation.
1178 */
1179
1180 #ifndef _CONFIG_H
1181 #define _CONFIG_H
1182 ''',
1183             headers = [
1184                 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1185                 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1186                 ('string.h', 'HAVE_STRING_H', 'c'),
1187                 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1188                 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1189                 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1190                 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1191                 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1192                 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1193                 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1194             ],
1195             functions = [
1196                 ('getcwd', 'HAVE_GETCWD', None),
1197                 ('stpcpy', 'HAVE_STPCPY', None),
1198                 ('strcasecmp', 'HAVE_STRCASECMP', None),
1199                 ('strdup', 'HAVE_STRDUP', None),
1200                 ('strtoul', 'HAVE_STRTOUL', None),
1201                 ('alloca', 'HAVE_ALLOCA', None),
1202                 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1203                 ('mempcpy', 'HAVE_MEMPCPY', None),
1204                 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1205                 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1206                 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1207                 ('setlocale', 'HAVE_SETLOCALE', None),
1208                 ('tsearch', 'HAVE_TSEARCH', None),
1209                 ('getegid', 'HAVE_GETEGID', None),
1210                 ('getgid', 'HAVE_GETGID', None),
1211                 ('getuid', 'HAVE_GETUID', None),
1212                 ('wcslen', 'HAVE_WCSLEN', None),
1213                 ('asprintf', 'HAVE_ASPRINTF', None),
1214                 ('wprintf', 'HAVE_WPRINTF', None),
1215                 ('snprintf', 'HAVE_SNPRINTF', None),
1216                 ('printf', 'HAVE_POSIX_PRINTF', None),
1217                 ('fcntl', 'HAVE_FCNTL', None),
1218             ],
1219             types = [
1220                 ('intmax_t', 'HAVE_INTMAX_T', None),
1221                 ('long double', 'HAVE_LONG_DOUBLE', None),
1222                 ('long long', 'HAVE_LONG_LONG', None),
1223                 ('wchar_t', 'HAVE_WCHAR_T', None),
1224                 ('wint_t', 'HAVE_WINT_T', None),
1225                 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1226                 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1227             ],
1228             libs = [
1229                 ('c', 'HAVE_LIBC'),
1230             ],
1231             custom_tests = [
1232                 (conf.CheckLC_MESSAGES(),
1233                     'HAVE_LC_MESSAGES',
1234                     'Define if your <locale.h> file defines LC_MESSAGES.'
1235                 ),
1236                 (conf.CheckIconvConst(),
1237                     'ICONV_CONST',
1238                     'Define as const if the declaration of iconv() needs const.',
1239                     '#define ICONV_CONST const',
1240                     '#define ICONV_CONST',
1241                 ),
1242                 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1243                 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1244                     'HAVE_INTMAX_T',
1245                     "Define to 1 if you have the `intmax_t' type."
1246                 ),
1247                 (env.has_key('nls') and env['nls'],
1248                     'ENABLE_NLS',
1249                     "Define to 1 if translation of program messages to the user's native anguage is requested.",
1250                 ),
1251             ],
1252             extra_items = [
1253                 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found')
1254             ],
1255             config_post = '#endif'
1256         )
1257
1258         # these keys are needed in env
1259         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1260             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1261             # USE_ASPELL etc does not go through result
1262             if result.has_key(key):
1263                 env[key] = result[key]
1264             env_cache[key] = env[key]
1265
1266 else:
1267     #
1268     # this comes as a big surprise, without this line
1269     # (doing nothing obvious), adding fast_start=yes
1270     # to a build with fast_start=no will result in a rebuild
1271     # Note that the exact header file to check does not matter
1272     conf.CheckCHeader('io.h')
1273     # only a few variables need to be rescanned
1274     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1275         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1276         env[key] = env_cache[key]
1277     #
1278     # nls related keys
1279     if env['nls'] and included_gettext:
1280         # only a few variables need to be rescanned
1281         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1282             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1283             env[key] = env_cache[key]
1284
1285 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1286 if env['nls'] and included_gettext:
1287     # libgnuintl.h.in => libintl.h
1288     env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1289     env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1290         [Copy('$TARGET', '$SOURCE')])
1291
1292 #
1293 # Finish auto-configuration
1294 env = conf.Finish()
1295
1296 #----------------------------------------------------------
1297 # Now set up our build process accordingly
1298 #----------------------------------------------------------
1299
1300 #
1301 # QT_LIB
1302 #
1303 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1304 # in their respective directory and specialized env.
1305 if frontend == 'qt3':
1306     # note: env.Tool('qt') my set QT_LIB to qt
1307     if platform_name == 'win32':
1308         qt_libs = ['qt-mt3']
1309     else:
1310         qt_libs = ['qt-mt']
1311     frontend_libs = qt_libs
1312 elif frontend == 'qt4':
1313     qt_libs = ['QtCore', 'QtGui']
1314     # set the right lib names
1315     if platform_name == 'win32':
1316         if mode == 'debug' and use_vc:
1317             qt_lib_suffix = 'd4'
1318         else:
1319             qt_lib_suffix = '4'
1320     else:
1321         if mode == 'debug':
1322             qt_lib_suffix = '_debug'
1323         else:
1324             qt_lib_suffix = ''
1325     frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1326
1327
1328 if platform_name in ['win32', 'cygwin']:
1329     # the final link step needs stdc++ to succeed under mingw
1330     # FIXME: shouldn't g++ automatically link to stdc++?
1331     if use_vc:
1332         system_libs = [env['ICONV_LIB'], 'shlwapi', 'shell32', 'advapi32', 'zdll']
1333     else:
1334         system_libs = [env['ICONV_LIB'], 'shlwapi', 'stdc++', 'z']
1335 elif platform_name == 'cygwin' and env['X11']:
1336     system_libs = [env['ICONV_LIB'], 'GL',  'Xmu', 'Xi', 'Xrender', 'Xrandr',
1337         'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 
1338         'resolv', 'pthread', 'z']
1339 else:
1340     system_libs = [env['ICONV_LIB'], 'z']
1341
1342 libs = [
1343     ('HAVE_LIBGDI32', 'gdi32'),
1344     ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1345     ('USE_ASPELL', aspell_lib),
1346     ('USE_ISPELL', 'ispell'),
1347     ('USE_PSPELL', 'pspell'),
1348 ]
1349
1350 for lib in libs:
1351     if env[lib[0]]:
1352         system_libs.append(lib[1])
1353
1354 #
1355 # Build parameters CPPPATH etc
1356 #
1357 if env['X11']:
1358     env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1359
1360 #
1361 # boost: for boost header files
1362 # BUILDDIR/common: for config.h
1363 # TOP_SRCDIR/src: for support/* etc
1364 #
1365 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1366 #
1367 # Separating boost directories from CPPPATH stops scons from building
1368 # the dependency tree for boost header files, and effectively reduce
1369 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1370 # boost headers, this is only done for system boost headers.
1371 if included_boost:
1372     env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1373 else:
1374     if use_vc:
1375         env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1376     else:
1377         env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1378
1379 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1380 if env['nls'] and included_gettext:
1381     env['CPPPATH'].append('$BUILDDIR/intl')
1382 #
1383 # QT_INC_PATH is not needed for *every* source file
1384 env['CPPPATH'].remove(qt_inc_path)
1385
1386 #
1387 # A Link script for cygwin see
1388 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1389 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1390 # for details
1391 #
1392 if platform_name == 'cygwin':
1393     ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1394     ld_script = utils.installCygwinLDScript(ld_script_path)
1395     env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1396         '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1397
1398 #
1399 # Report results
1400 #
1401 # fill in the version info
1402 env['VERSION_INFO'] = '''Configuration
1403   Host type:                      %s
1404   Special build flags:            %s
1405   C   Compiler:                   %s
1406   C   Compiler flags:             %s %s
1407   C++ Compiler:                   %s
1408   C++ Compiler LyX flags:         %s
1409   C++ Compiler flags:             %s %s
1410   Linker flags:                   %s
1411   Linker user flags:              %s
1412 Build info:
1413   Builing directory:              %s
1414   Local library directory:        %s
1415   Libraries paths:                %s
1416   Boost libraries:                %s
1417   Frontend libraries:             %s
1418   System libraries:               %s
1419   include search path:            %s
1420 Frontend:
1421   Frontend:                       %s
1422   Packaging:                      %s
1423   LyX dir:                        %s
1424   LyX files dir:                  %s
1425 ''' % (platform_name,
1426     env.subst('$CCFLAGS'), env.subst('$CC'),
1427     env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1428     env.subst('$CXX'), env.subst('$CXXFLAGS'),
1429     env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1430     env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1431     env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1432     str(env['LIBPATH']), str(boost_libraries),
1433     str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1434     frontend, packaging_method,
1435     prefix, env['LYX_DIR'])
1436
1437 if frontend in ['qt3', 'qt4']:
1438     env['VERSION_INFO'] += '''  include dir:                    %s
1439   library dir:                    %s
1440   X11:                            %s
1441 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1442
1443 if not fast_start:
1444     print env['VERSION_INFO']
1445
1446 #
1447 # Mingw command line may be too short for our link usage,
1448 # Here we use a trick from scons wiki
1449 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1450 #
1451 # I also would like to add logging (commands only) capacity to the
1452 # spawn system.
1453 logfile = env.get('logfile', default_log_file)
1454 if logfile != '' or platform_name == 'win32':
1455     import time
1456     utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1457         info = '''# This is a log of commands used by scons to build lyx
1458 # Time: %s
1459 # Command: %s
1460 # Info: %s
1461 ''' % (time.asctime(), ' '.join(sys.argv),
1462     env['VERSION_INFO'].replace('\n','\n# ')) )
1463
1464
1465 # Cleanup stuff
1466 #
1467 # -h will print out help info
1468 Help(opts.GenerateHelpText(env))
1469
1470 # save environment settings (for fast_start option)
1471 cache_file = open(env_cache_file, 'w')
1472 cPickle.dump(env_cache, cache_file)
1473 cache_file.close()
1474
1475
1476 #----------------------------------------------------------
1477 # Start building
1478 #----------------------------------------------------------
1479 # this has been the source of problems on some platforms...
1480 # I find that I need to supply it with full path name
1481 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1482 # this usage needs further investigation.
1483 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1484
1485 print "Building all targets recursively"
1486
1487 if env.has_key('rebuild'):
1488     rebuild_targets = env['rebuild'].split(',')
1489     if 'none' in rebuild_targets or 'no' in rebuild_targets:
1490         rebuild_targets = []
1491     elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1492         # None: let scons decide which components to build
1493         # Forcing all components to be rebuilt is in theory not necessary
1494         rebuild_targets = None    
1495 else:
1496     rebuild_targets = None
1497
1498 def libExists(libname):
1499     ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1500     return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1501
1502 def appExists(apppath, appname):
1503     ''' Check whether or not application already exists'''
1504     return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1505
1506 targets = BUILD_TARGETS
1507 # msvc need to pass full target name, so I have to look for path/lyx etc
1508 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1509     or 'install' in targets or 'all' in targets
1510 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1511 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1512 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1513 build_mathed = build_lyx or 'mathed' in targets
1514 build_insets = build_lyx or 'insets' in targets
1515 build_frontends = build_lyx or 'frontends' in targets
1516 build_graphics = build_lyx or 'graphics' in targets
1517 build_controllers = build_lyx or 'controllers' in targets
1518 build_client = True in ['client' in x for x in targets] \
1519     or 'install' in targets or 'all' in targets
1520 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1521     or 'install' in targets or 'all' in targets
1522 build_lyxbase = build_lyx or 'lyxbase' in targets
1523 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1524 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1525 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1526 build_msvs_projects = use_vc and 'msvs_projects' in targets
1527
1528
1529 # now, if rebuild_targets is specified, do not rebuild some targets
1530 if rebuild_targets is not None:
1531     #
1532     def ifBuildLib(name, libname, old_value):
1533         # explicitly asked to rebuild
1534         if name in rebuild_targets:
1535             return True
1536         # else if not rebuild, and if the library already exists
1537         elif libExists(libname):
1538             return False
1539         # do not change the original value
1540         else:
1541             return old_value
1542     build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1543     build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1544     build_support = ifBuildLib('support', 'support', build_support)
1545     build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1546     build_insets = ifBuildLib('insets', 'insets', build_insets)
1547     build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1548     build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1549     build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1550     build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1551     build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1552     build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1553     #
1554     def ifBuildApp(name, appname, old_value):
1555         # explicitly asked to rebuild
1556         if name in rebuild_targets:
1557             return True
1558         # else if not rebuild, and if the library already exists
1559         elif appExists(name, appname):
1560             return False
1561         # do not change the original value
1562         else:
1563             return old_value
1564     build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1565     build_client = ifBuildApp('client', 'lyxclient', build_client)
1566
1567 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1568 if build_qt3:
1569     frontend = 'qt3'
1570 elif build_qt4:
1571     frontend = 'qt4'
1572
1573
1574 if build_boost:
1575     #
1576     # boost libraries
1577     #
1578     # special builddir
1579     env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1580
1581     boostenv = env.Copy()
1582     #
1583     # boost use its own config.h
1584     boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1585     boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1586
1587     for lib in boost_libs:
1588         print 'Processing files in boost/libs/%s/src...' % lib
1589         boostlib = boostenv.StaticLibrary(
1590             target = '$LOCALLIBPATH/included_boost_%s' % lib,
1591             source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1592         )
1593         Alias('boost', boostlib)
1594
1595
1596 if build_intl:
1597     #
1598     # intl
1599     #
1600     intlenv = env.Copy()
1601
1602     print "Processing files in intl..."
1603
1604     env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1605
1606     # we need the original C compiler for these files
1607     intlenv['CC'] = C_COMPILER
1608     intlenv['CCFLAGS'] = C_CCFLAGS
1609     if use_vc:
1610         intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1611     # intl does not use global config.h
1612     intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1613
1614     intlenv.Append(CCFLAGS = [
1615         r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1616         r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1617         r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1618         '-DIN_LIBINTL',
1619         '-DENABLE_RELOCATABLE=1',
1620         '-DIN_LIBRARY',
1621         r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1622         '-DNO_XMALLOC',
1623         '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1624         '-Drelocate=libintl_relocate',
1625         '-DDEPENDS_ON_LIBICONV=1',
1626         '-DHAVE_CONFIG_H'
1627         ]
1628     )
1629
1630     intl = intlenv.StaticLibrary(
1631         target = '$LOCALLIBPATH/included_intl',
1632         LIBS = ['c'],
1633         source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1634     )
1635     Alias('intl', intl)
1636
1637
1638 #
1639 # Now, src code under src/
1640 #
1641 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1642
1643
1644 if build_support:
1645     #
1646     # src/support
1647     #
1648     print "Processing files in src/support..."
1649
1650     env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1651
1652     support = env.StaticLibrary(
1653         target = '$LOCALLIBPATH/support',
1654         source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1655     )
1656     Alias('support', support)
1657
1658
1659 if build_mathed:
1660     #
1661     # src/mathed
1662     #
1663     print "Processing files in src/mathed..."
1664     #
1665     mathed = env.StaticLibrary(
1666         target = '$LOCALLIBPATH/mathed',
1667         source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1668     )
1669     Alias('mathed', mathed)
1670
1671
1672 if build_insets:
1673     #
1674     # src/insets
1675     #
1676     print "Processing files in src/insets..."
1677     #
1678     insets = env.StaticLibrary(
1679         target = '$LOCALLIBPATH/insets',
1680         source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1681     )
1682     Alias('insets', insets)
1683
1684
1685 if build_frontends:
1686     #
1687     # src/frontends
1688     #
1689     print "Processing files in src/frontends..."
1690
1691     frontends = env.StaticLibrary(
1692         target = '$LOCALLIBPATH/frontends',
1693         source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1694     )
1695     Alias('frontends', frontends)
1696
1697
1698 if build_graphics:
1699     #
1700     # src/graphics
1701     #
1702     print "Processing files in src/graphics..."
1703
1704     graphics = env.StaticLibrary(
1705         target = '$LOCALLIBPATH/graphics',
1706         source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1707     )
1708     Alias('graphics', graphics)
1709
1710
1711 if build_controllers:
1712     #
1713     # src/frontends/controllers
1714     #
1715     print "Processing files in src/frontends/controllers..."
1716
1717     controllers = env.StaticLibrary(
1718         target = '$LOCALLIBPATH/controllers',
1719         source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1720     )
1721     Alias('controllers', controllers)
1722
1723
1724 #
1725 # src/frontend/qt3/4
1726 #
1727 if build_qt3 or build_qt4:
1728     env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1729
1730 if build_qt3:
1731     print "Processing files in src/frontends/qt3..."
1732
1733     qt3env = env.Copy()
1734     # disable auto scan to speed up non build time
1735     qt3env['QT_AUTOSCAN'] = 0
1736     qt3env['QT_MOCHPREFIX'] = ''
1737
1738     # load qt3 tools
1739     qt3env.Tool('qt')
1740
1741     qt3env.AppendUnique(CPPPATH = [
1742         '$BUILDDIR/common',
1743         '$BUILDDIR/common/images',
1744         '$BUILDDIR/common/frontends',
1745         '$BUILDDIR/common/frontends/qt3',
1746         '$BUILDDIR/common/frontends/controllers',
1747         qt_inc_path]
1748     )
1749
1750     qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1751     
1752     # manually moc and uic files for better performance
1753     qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1754
1755     qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1756         src_frontends_qt3_ui_files]
1757
1758     qt3_uiced_cc_files = []
1759     for x in qt3_uiced_files:
1760         qt3_uiced_cc_files.extend(x[1:])
1761
1762     qt3 = qt3env.StaticLibrary(
1763         target = '$LOCALLIBPATH/qt3',
1764         source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1765             + qt3_uiced_cc_files
1766     )
1767     Alias('qt3', qt3)
1768
1769
1770 if build_qt4:
1771     print "Processing files in src/frontends/qt4..."
1772
1773     qt4env = env.Copy()
1774     qt4env['QT_AUTOSCAN'] = 0
1775
1776     # local qt4 toolset from
1777     # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1778     #
1779     # NOTE: I have to patch qt4.py since it does not automatically
1780     # process .C file!!! (add to cxx_suffixes )
1781     #
1782     qt4env.Tool('qt4', [scons_dir])
1783     qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1784
1785     qt4env.AppendUnique(CPPPATH = [
1786         '$BUILDDIR/common',
1787         '$BUILDDIR/common/images',
1788         '$BUILDDIR/common/frontends',
1789         '$BUILDDIR/common/frontends/qt4',
1790         '$BUILDDIR/common/frontends/controllers',
1791         qt_inc_path
1792         ]
1793     )
1794
1795     # FIXME: replace by something from pkg_config
1796     qt4env.Append(CCFLAGS = [
1797         '-DHAVE_CONFIG_H',
1798         '-DQT_CLEAN_NAMESPACE',
1799         '-DQT_GENUINE_STR',
1800         '-DQT_NO_STL',
1801         '-DQT_NO_KEYWORDS',
1802         ]
1803     )
1804
1805
1806     qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1807
1808     #
1809     # Compile resources
1810     #
1811     resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1812         ["$BUILDDIR/common/frontends/qt4/ui/%s" % x for x in src_frontends_qt4_ui_files]]
1813
1814     #
1815     # moc qt4_moc_files, the moced files are included in the original files
1816     #
1817     qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1818
1819     qt4 = qt4env.StaticLibrary(
1820         target = '$LOCALLIBPATH/qt4',
1821         source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1822     )
1823     Alias('qt4', qt4)
1824
1825
1826 if build_client:
1827     #
1828     # src/client
1829     #
1830     env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1831
1832     print "Processing files in src/client..."
1833
1834     if env['HAVE_FCNTL']:
1835         client = env.Program(
1836             target = '$BUILDDIR/common/client/lyxclient',
1837             LIBS = ['support'] + intl_libs + system_libs +
1838                 socket_libs + boost_libraries,
1839             source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1840         )
1841         Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1842             client, [Copy('$TARGET', '$SOURCE')]))
1843     else:
1844         client = None
1845     Alias('client', client)
1846 else:
1847     if env['HAVE_FCNTL']:
1848         # define client even if lyxclient is not built with rebuild=no
1849         client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1850     else:
1851         client = None
1852
1853
1854 if build_tex2lyx:
1855     #
1856     # tex2lyx
1857     #
1858     print "Processing files in src/tex2lyx..."
1859
1860     tex2lyx_env = env.Copy()
1861     #
1862     tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1863     tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1864
1865     for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1866         'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1867         env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1868             [Copy('$TARGET', '$SOURCE')])
1869
1870     tex2lyx = tex2lyx_env.Program(
1871         target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1872         LIBS = ['support'] + boost_libraries + system_libs,
1873         source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1874     )
1875     Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1876         tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1877     Alias('tex2lyx', tex2lyx)
1878 else:
1879     # define tex2lyx even if tex2lyx is not built with rebuild=no
1880     tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1881
1882
1883 if build_lyxbase:
1884     #
1885     # src/
1886     #
1887     print "Processing files in src..."
1888
1889     env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1890
1891     if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1892         src_post_files.append('aspell.C')
1893     elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1894         src_post_files.append('pspell.C')
1895     elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1896         src_post_files.append('ispell.C')
1897
1898     # msvc requires at least one source file with main()
1899     # so I exclude main.C from lyxbase
1900     lyxbase_pre = env.StaticLibrary(
1901         target = '$LOCALLIBPATH/lyxbase_pre',
1902         source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1903     )
1904     lyxbase_post = env.StaticLibrary(
1905         target = '$LOCALLIBPATH/lyxbase_post',
1906         source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1907     )
1908     Alias('lyxbase', lyxbase_pre)
1909     Alias('lyxbase', lyxbase_post)
1910
1911
1912 if build_lyx:
1913     #
1914     # Build lyx with given frontend
1915     #
1916     lyx = env.Program(
1917         target = '$BUILDDIR/$frontend/lyx',
1918         source = ['$BUILDDIR/common/main.C'],
1919         LIBS = [
1920             'lyxbase_pre',
1921             'mathed',
1922             'insets',
1923             'frontends',
1924             frontend,
1925             'controllers',
1926             'graphics',
1927             'support',
1928             'lyxbase_post',
1929             ] +
1930             boost_libraries +
1931             frontend_libs +
1932             intl_libs +
1933             socket_libs +
1934             system_libs
1935     )
1936     # [/path/to/lyx.ext] => lyx-qt3.ext
1937     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1938     Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1939         [Copy('$TARGET', '$SOURCE')]))
1940     Alias('lyx', lyx)
1941 else:
1942     # define lyx even if lyx is not built with rebuild=no
1943     lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1944
1945
1946 if build_msvs_projects:
1947     def build_project(target, full_target = None,
1948         src = [], inc = [], res = [], rebuildTargetOnly = True):
1949         ''' build mavs project files
1950             target:      alias (correspond to directory name)
1951             full_target: full path/filename of the target
1952             src:         source files
1953             inc:         include files
1954             res:         resource files
1955             rebuildTargetOnly:     whether or not only rebuild this target
1956
1957         For non-debug-able targets like static libraries, target (alias) is
1958         enough to build the target. For executable targets, msvs need to know
1959         the full path to start debug them.
1960         '''
1961         if rebuildTargetOnly:
1962             cmds = 'fast_start=yes rebuild='+target
1963         else:
1964             cmds = 'fast_start=yes'
1965         if full_target is None:
1966             build_target = target
1967         else:
1968             build_target = full_target
1969         # project
1970         proj = env.MSVSProject(
1971             target = target + env['MSVSPROJECTSUFFIX'],
1972             # this allows easy access to header files (along with source)
1973             srcs = [env.subst(x) for x in src + inc],
1974             incs = [env.subst('$TOP_SRCDIR/src/config.h')],
1975             localincs = [env.subst(x) for x in inc],
1976             resources = [env.subst(x) for x in res],
1977             buildtarget = build_target,
1978             cmdargs = cmds,
1979             variant = 'Debug'
1980         )
1981         Alias('msvs_projects', proj)
1982     #
1983     boost_src = []
1984     for lib in boost_libs:
1985         boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1986     build_project('boost', src = boost_src)
1987     #
1988     build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files], 
1989         inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
1990     #
1991     build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
1992         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
1993     #
1994     build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
1995         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
1996     #
1997     build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files], 
1998         inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
1999     #
2000     build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files], 
2001         inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
2002     #
2003     build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files], 
2004         inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
2005     #
2006     build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files], 
2007         inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
2008     #
2009     build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2010         inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2011         res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
2012     #
2013     build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2014         inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2015         res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
2016     #
2017     build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
2018         inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
2019         rebuildTargetOnly = False,
2020         full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2021     #
2022     build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2023         inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2024         rebuildTargetOnly = False,
2025         full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2026     #
2027     build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2028         inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2029     #
2030     if frontend == 'qt3':
2031         build_project('lyx', 
2032             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2033                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2034                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2035                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2036                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2037                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2038                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2039                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2040             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2041                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2042                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2043                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2044                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2045                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2046                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2047                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2048             res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2049             rebuildTargetOnly = False,
2050             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2051     else:
2052         build_project('lyx', 
2053             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2054                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2055                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2056                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2057                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2058                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2059                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2060                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2061             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2062                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2063                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2064                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2065                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2066                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2067                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2068                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2069             res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2070             rebuildTargetOnly = False,
2071             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2072
2073
2074 if build_po:
2075     #
2076     # po/
2077     #
2078     print 'Processing files in po...'
2079
2080     import glob
2081     # handle po files
2082     #
2083     # files to translate
2084     transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2085     # possibly *only* handle these languages
2086     languages = None
2087     if env.has_key('languages'):
2088         languages = env.make_list(env['lanauges'])
2089     # use defulat msgfmt
2090     gmo_files = []
2091     if not env['MSGFMT']:
2092         print 'msgfmt does not exist. Can not process po files'
2093     else:
2094         # create a builder
2095         env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2096         #
2097         for f in transfiles:
2098             # get filename
2099             fname = os.path.split(f)[1]
2100             # country code
2101             country = fname.split('.')[0]
2102             #
2103             if not languages or country in languages:
2104                 gmo_files.extend(env.Transfiles(f))
2105
2106
2107 if 'install' in targets:
2108     #
2109     # this part is a bit messy right now. Since scons will provide
2110     # --DESTDIR option soon, at least the dest_dir handling can be 
2111     # removed later.
2112     #
2113     # how to join dest_dir and prefix
2114     def joinPaths(path1, path2):
2115         ''' join path1 and path2, do not use os.path.join because
2116             under window, c:\destdir\d:\program is invalid '''
2117         if path1 is None:
2118             return os.path.normpath(path2)
2119         # separate drive letter
2120         (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2121         # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2122         return os.path.join(os.path.normpath(path1), path[1:])
2123     #
2124     # install to dest_dir/prefix
2125     dest_dir = env.get('DESTDIR', None)
2126     dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2127     # create the directory if needed
2128     if not os.path.isdir(dest_prefix_dir):
2129         try:
2130             os.makedirs(dest_prefix_dir)
2131         except:
2132             pass
2133         if not os.path.isdir(dest_prefix_dir):
2134             print 'Can not create directory', dest_prefix_dir
2135             Exit(3)
2136     #
2137     if env.has_key('exec_prefix'):
2138         bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2139     else:
2140         bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2141     if add_suffix:
2142         share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2143     else:
2144         share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2145     man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2146     locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2147     #
2148     import glob
2149     #
2150     # install executables (lyxclient may be None)
2151     #
2152     if add_suffix:
2153         version_suffix = program_suffix
2154     else:
2155         version_suffix = ''
2156     #
2157     # install lyx
2158     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2159     target = os.path.join(bin_dest_dir, target_name)
2160     env.InstallAs(target, lyx)
2161     Alias('install', target)
2162     # install lyx as lyx-qt3
2163     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2164     target = os.path.join(bin_dest_dir, target_name)
2165     env.InstallAs(target, lyx)
2166     Alias('install', target)
2167     #
2168     # install tex2lyx
2169     target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2170     target = os.path.join(bin_dest_dir, target_name)
2171     env.InstallAs(target, tex2lyx)
2172     Alias('install', target)
2173     #
2174     # install lyxclient, may not exist
2175     if client != None:
2176         target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2177         target = os.path.join(bin_dest_dir, target_name)
2178         env.InstallAs(target, client)
2179         Alias('install', target)
2180     #
2181     # share/lyx
2182     dirs = []
2183     for (dir,files) in [
2184             ('.', lib_files),  
2185             ('clipart', lib_clipart_files),
2186             ('examples', lib_examples_files),
2187             ('images', lib_images_files),
2188             ('images/math', lib_images_math_files),
2189             ('bind', lib_bind_files),
2190             ('kbd', lib_kbd_files),
2191             ('layouts', lib_layouts_files),
2192             ('scripts', lib_scripts_files),
2193             ('templates', lib_templates_files),
2194             ('tex', lib_tex_files),
2195             ('ui', lib_ui_files),
2196             ('doc', lib_doc_files),
2197             ('lyx2lyx', lib_lyx2lyx_files)]:
2198         dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2199             [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2200     
2201     # lyx1.4.x does not have lyx2lyx_version.py.in
2202     if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2203         # subst and install this file
2204         env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2205             '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2206         Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2207     Alias('install', dirs)
2208     # man
2209     env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2210         env.subst('$TOP_SRCDIR/lyx.man'))
2211     env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2212         env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2213     env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2214         env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2215     Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2216         x in ['lyx', 'tex2lyx', 'lyxclient']])
2217     # locale files?
2218     # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2219     for gmo in gmo_files:
2220         lan = os.path.split(str(gmo))[1].split('.')[0]
2221         dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2222         env.InstallAs(dest_file, gmo)
2223         Alias('install', dest_file)
2224
2225
2226 Default('lyx')
2227 Alias('all', ['lyx', 'client', 'tex2lyx'])