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