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