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