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