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