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