]> git.lyx.org Git - features.git/blob - development/scons/SConstruct
Scons: add SIZEOF_WCHAR_T
[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         'CheckSizeOfWChar' : utils.checkSizeOfWChar,
657     }
658 )
659
660 # pkg-config? (if not, we use hard-coded options)
661 if not fast_start:
662     if conf.CheckPkgConfig('0.15.0'):
663         env['HAS_PKG_CONFIG'] = True
664     else:
665         print 'pkg-config >= 0.1.50 is not found'
666         env['HAS_PKG_CONFIG'] = False
667     env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
668 else:
669     env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
670
671 # zlib? This is required. (fast_start assumes the existance of zlib)
672 if not fast_start:
673     if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
674         or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
675         print 'Did not find zdll.lib or zlib.h, exiting!'
676         Exit(1)
677     if conf.CheckLib('iconv'):
678         env['ICONV_LIB'] = ['iconv']
679     elif conf.CheckLib('libiconv'):
680         env['ICONV_LIB'] = ['libiconv']
681     elif conf.CheckFunc('iconv_open'):
682         env['ICONV_LIB'] = []
683     else:
684         print 'Did not find iconv or libiconv, exiting!'
685         Exit(1)
686     env_cache['ICONV_LIB'] = env['ICONV_LIB']
687 else:
688     env['ICONV_LIB'] = env_cache['ICONV_LIB']
689
690 # qt libraries?
691 if not fast_start:
692     #
693     # qt3 does not use pkg_config
694     if frontend == 'qt3':
695         # windows lib name is qt-mt3
696         if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \
697             and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'):
698             print 'Did not find qt libraries, exiting!'
699             Exit(1)
700     elif frontend == 'qt4':
701         succ = False
702         # first: try pkg_config
703         if env['HAS_PKG_CONFIG']:
704             succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
705             # FIXME: use pkg_config information?
706             #env['QT4_PKG_CONFIG'] = succ
707         # second: try to link to it
708         if not succ:
709             # Under linux, I can test the following perfectly
710             # Under windows, lib names need to passed as libXXX4.a ...
711             succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
712                 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
713         # third: try to look up the path
714         if not succ:
715             succ = True
716             for lib in ['QtCore', 'QtGui']:
717                 # windows version has something like QtGui4 ...
718                 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
719                     os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
720                     succ = False
721                     break
722         # still can not find it
723         if succ:
724             print "Qt4 libraries are found."
725         else:
726             print 'Did not find qt libraries, exiting!'
727             Exit(1)
728
729 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
730 if use_vc:
731     if frontend == 'qt3':
732         manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest')
733     elif frontend == 'qt4':
734         if mode == 'debug':
735             manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
736         else:
737             manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
738     if os.path.isfile(manifest):
739         env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
740
741 # check socket libs
742 if not fast_start:
743     socket_libs = []
744     if conf.CheckLib('socket'):
745         socket_libs.append('socket')
746     # nsl is the network services library and provides a
747     # transport-level interface to networking services.
748     if conf.CheckLib('nsl'):
749         socket_libs.append('nsl')
750     env_cache['SOCKET_LIBS'] = socket_libs
751 else:
752     socket_libs = env_cache['SOCKET_LIBS']
753
754 # check available boost libs (since lyx1.4 does not use iostream)
755 boost_libs = []
756 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
757     if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
758         boost_libs.append(lib)
759
760 if not fast_start:
761     # check boost libraries
762     boost_opt = ARGUMENTS.get('boost', 'auto')
763     # check for system boost
764     lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
765     inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
766     # default to $BUILDDIR/libs (use None since this path will be added anyway)
767     boost_libpath = None
768     # here I assume that all libraries are in the same directory
769     if boost_opt == 'included':
770         boost_libraries = ['included_boost_%s' % x for x in boost_libs]
771         included_boost = True
772         env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
773     elif boost_opt == 'auto':
774         res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
775         # if not found, use local boost
776         if res[0] is None:
777             boost_libraries = ['included_boost_%s' % x for x in boost_libs]
778             included_boost = True
779             env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
780         else:
781             included_boost = False
782             (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
783     elif boost_opt == 'system':
784         res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
785         if res[0] is None:
786             print "Can not find system boost libraries with version %s " % boost_version
787             print "Please supply a path through extra_lib_path and try again."
788             print "Or use boost=included to use included boost libraries."
789             Exit(2)
790         else:
791             included_boost = False
792             (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
793     env_cache['BOOST_LIBRARIES'] = boost_libraries
794     env_cache['INCLUDED_BOOST'] = included_boost
795     env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
796     env_cache['BOOST_LIBPATH'] = boost_libpath
797 else:
798     boost_libraries = env_cache['BOOST_LIBRARIES']
799     included_boost = env_cache['INCLUDED_BOOST']
800     env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
801     boost_libpath = env_cache['BOOST_LIBPATH']
802
803 if boost_libpath is not None:
804     env.AppendUnique(LIBPATH = [boost_libpath])
805
806
807 env['ENABLE_NLS'] = env['nls']
808
809 if not fast_start:
810     if not env['ENABLE_NLS']:
811         intl_libs = []
812         included_gettext = False
813     else:
814         # check gettext libraries
815         gettext_opt = ARGUMENTS.get('gettext', 'auto')
816         # check for system gettext
817         succ = False
818         if gettext_opt in ['auto', 'system']:
819             if conf.CheckLib('intl'):
820                 included_gettext = False
821                 intl_libs = ['intl']
822                 succ = True
823             else: # no found
824                 if gettext_opt == 'system':
825                     print "Can not find system gettext library"
826                     print "Please supply a path through extra_lib_path and try again."
827                     print "Or use gettext=included to use included gettext libraries."
828                     Exit(2)
829         # now, auto and succ = false, or gettext=included
830         if not succ:
831             # we do not need to set LIBPATH now.
832             included_gettext = True
833             intl_libs = ['included_intl']
834     env_cache['INCLUDED_GETTEXT'] = included_gettext
835     env_cache['INTL_LIBS'] = intl_libs
836 else:
837     included_gettext = env_cache['INCLUDED_GETTEXT']
838     intl_libs = env_cache['INTL_LIBS']
839
840 #
841 # check for msgfmt command
842 if not fast_start:
843     env['MSGFMT'] = conf.CheckCommand('msgfmt')
844     env_cache['MSGFMT'] = env['MSGFMT']
845 else:
846     env['MSGFMT'] = env_cache['MSGFMT']
847
848 # cygwin packaging requires the binaries to be stripped
849 if platform_name == 'cygwin':
850     if not fast_start:
851         env['STRIP'] = conf.CheckCommand('strip')
852         env_cache['STRIP'] = env['STRIP']
853     else:
854         env['STRIP'] = env_cache['STRIP']
855
856 # check uic and moc commands for qt frontends
857 if not fast_start:
858     if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
859         or conf.CheckCommand('moc') == None):
860         print 'uic or moc command is not found for frontend', frontend
861         Exit(1)
862
863 #
864 # Customized builders
865 #
866 # install customized builders
867 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
868
869
870 #----------------------------------------------------------
871 # Generating config.h
872 #----------------------------------------------------------
873 aspell_lib = 'aspell'
874 # assume that we use aspell, aspelld compiled for msvc
875 if platform_name == 'win32' and mode == 'debug' and use_vc:
876     aspell_lib = 'aspelld'
877
878 # check the existence of config.h
879 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
880 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
881 if not fast_start or not os.path.isfile(boost_config_h) \
882     or not os.path.isfile(config_h):
883     #
884     print "Creating %s..." % boost_config_h
885     #
886     utils.createConfigFile(conf,
887         config_file = boost_config_h,
888         config_pre = '''/* boost/config.h.  Generated by SCons.  */
889
890 /* -*- C++ -*- */
891 /*
892 * \file config.h
893 * This file is part of LyX, the document processor.
894 * Licence details can be found in the file COPYING.
895 *
896 * This is the compilation configuration file for LyX.
897 * It was generated by scon.
898 * You might want to change some of the defaults if something goes wrong
899 * during the compilation.
900 */
901
902 #ifndef _BOOST_CONFIG_H
903 #define _BOOST_CONFIG_H
904 ''',
905         headers = [
906             ('ostream', 'HAVE_OSTREAM', 'cxx'),
907             ('locale', 'HAVE_LOCALE', 'cxx'),
908             ('sstream', 'HAVE_SSTREAM', 'cxx'),
909             #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
910         ],
911         custom_tests = [
912             (env.has_key('assertions') and env['assertions'],
913                 'ENABLE_ASSERTIONS',
914                 'Define if you want assertions to be enabled in the code'
915             ),
916         ],
917         config_post = '''
918
919 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
920 #  define USE_BOOST_FORMAT 1
921 #else
922 #  define USE_BOOST_FORMAT 0
923 #endif
924
925 #if !defined(ENABLE_ASSERTIONS)
926 #  define BOOST_DISABLE_ASSERTS 1
927 #endif
928 #define BOOST_ENABLE_ASSERT_HANDLER 1
929
930 #define BOOST_DISABLE_THREADS 1
931 #define BOOST_NO_WSTRING 1
932
933 #ifdef __CYGWIN__
934 #  define BOOST_POSIX 1
935 #  define BOOST_POSIX_API 1
936 #  define BOOST_POSIX_PATH 1
937 #endif
938
939 #define BOOST_ALL_NO_LIB 1
940
941 #if defined(HAVE_NEWAPIS_H)
942 #  define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
943 #endif
944
945 #endif
946 '''
947     )
948     #
949     print "\nGenerating %s..." % config_h
950
951     # AIKSAURUS_H_LOCATION
952     if (conf.CheckCXXHeader("Aiksaurus.h")):
953         aik_location = '<Aiksaurus.h>'
954     elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
955         aik_location = '<Aiksaurus/Aiksaurus.h>'
956     else:
957         aik_location = ''
958
959     # determine headers to use
960     spell_opt = ARGUMENTS.get('spell', 'auto')
961     env['USE_ASPELL'] = False
962     env['USE_PSPELL'] = False
963     env['USE_ISPELL'] = False
964     if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
965         spell_engine = 'USE_ASPELL'
966     elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
967         spell_engine = 'USE_PSPELL'
968     elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
969         spell_engine = 'USE_ISPELL'
970     else:
971         spell_engine = None
972
973     if spell_engine is not None:
974         env[spell_engine] = True
975     else:
976         if spell_opt == 'auto':
977             print "Warning: Can not locate any spell checker"
978         elif spell_opt != 'no':
979             print "Warning: Can not locate specified spell checker:", spell_opt
980             Exit(1)
981
982     # check arg types of select function
983     (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
984
985     # check the size of wchar_t
986     sizeof_wchar_t = conf.CheckSizeOfWChar()
987     # something wrong
988     if sizeof_wchar_t == 0:
989         print 'Error: Can not determine the size of wchar_t.'
990         Exit(1)
991
992     #
993     # create config.h
994     result = utils.createConfigFile(conf,
995         config_file = config_h,
996         config_pre = '''/* config.h.  Generated by SCons.  */
997
998 /* -*- C++ -*- */
999 /*
1000 * \file config.h
1001 * This file is part of LyX, the document processor.
1002 * Licence details can be found in the file COPYING.
1003 *
1004 * This is the compilation configuration file for LyX.
1005 * It was generated by scon.
1006 * You might want to change some of the defaults if something goes wrong
1007 * during the compilation.
1008 */
1009
1010 #ifndef _CONFIG_H
1011 #define _CONFIG_H
1012 ''',
1013         headers = [
1014             ('io.h', 'HAVE_IO_H', 'c'),
1015             ('limits.h', 'HAVE_LIMITS_H', 'c'),
1016             ('locale.h', 'HAVE_LOCALE_H', 'c'),
1017             ('process.h', 'HAVE_PROCESS_H', 'c'),
1018             ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
1019             ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
1020             ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
1021             ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
1022             ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
1023             ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
1024             ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1025             ('utime.h', 'HAVE_UTIME_H', 'c'),
1026             ('direct.h', 'HAVE_DIRECT_H', 'c'),
1027             ('istream', 'HAVE_ISTREAM', 'cxx'),
1028             ('ios', 'HAVE_IOS', 'cxx'),
1029         ],
1030         functions = [
1031             ('open', 'HAVE_OPEN', None),
1032             ('close', 'HAVE_CLOSE', None),
1033             ('popen', 'HAVE_POPEN', None),
1034             ('pclose', 'HAVE_PCLOSE', None),
1035             ('_open', 'HAVE__OPEN', None),
1036             ('_close', 'HAVE__CLOSE', None),
1037             ('_popen', 'HAVE__POPEN', None),
1038             ('_pclose', 'HAVE__PCLOSE', None),
1039             ('getpid', 'HAVE_GETPID', None),
1040             ('_getpid', 'HAVE__GETPID', None),
1041             ('mkdir', 'HAVE_MKDIR', None),
1042             ('_mkdir', 'HAVE__MKDIR', None),
1043             ('mktemp', 'HAVE_MKTEMP', None),
1044             ('mkstemp', 'HAVE_MKSTEMP', None),
1045             ('strerror', 'HAVE_STRERROR', None),
1046             ('count', 'HAVE_STD_COUNT', '''
1047 #include <algorithm>
1048 int count()
1049 {
1050     char a[] = "hello";
1051     return std::count(a, a+5, 'l');
1052 }
1053 '''),
1054             ('getcwd', 'HAVE_GETCWD', None),
1055             ('setenv', 'HAVE_SETENV', None),
1056             ('putenv', 'HAVE_PUTENV', None),
1057             ('fcntl', 'HAVE_FCNTL', None),
1058         ],
1059         types = [
1060             ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1061                 '#include <streambuf>\n#include <istream>')
1062         ],
1063         libs = [
1064             ('gdi32', 'HAVE_LIBGDI32'),
1065             (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1066         ],
1067         custom_tests = [
1068             (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1069                 'HAVE_PID_T',
1070                 'Define is sys/types.h does not have pid_t',
1071                 '',
1072                 '#define pid_t int',
1073             ),
1074             (conf.CheckCXXGlobalCstd(),
1075                 'CXX_GLOBAL_CSTD',
1076                 'Define if your C++ compiler puts C library functions in the global namespace'
1077             ),
1078             (conf.CheckMkdirOneArg(),
1079                 'MKDIR_TAKES_ONE_ARG',
1080                 'Define if mkdir takes only one argument.'
1081             ),
1082             (conf.CheckIconvConst(),
1083                 'ICONV_CONST',
1084                 'Define as const if the declaration of iconv() needs const.',
1085                 '#define ICONV_CONST const',
1086                 '#define ICONV_CONST',
1087             ),
1088             (conf.CheckLC_MESSAGES(),
1089                 'HAVE_LC_MESSAGES',
1090                 'Define if your <locale.h> file defines LC_MESSAGES.'
1091             ),
1092             (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1093             (env['nls'],
1094                 'ENABLE_NLS',
1095                 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1096             ),
1097             (env['nls'] and not included_gettext,
1098                 'HAVE_GETTEXT',
1099                 'Define to 1 if using system gettext library'
1100             ),
1101             (env.has_key('warnings') and env['warnings'],
1102                 'WITH_WARNINGS',
1103                 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1104             ),
1105             (env.has_key('concept_checks') and env['concept_checks'],
1106                 '_GLIBCXX_CONCEPT_CHECKS',
1107                 'libstdc++ concept checking'
1108             ),
1109             (env.has_key('stdlib_debug') and env['stdlib_debug'],
1110                 '_GLIBCXX_DEBUG',
1111                 'libstdc++ debug mode'
1112             ),
1113             (env.has_key('stdlib_debug') and env['stdlib_debug'],
1114                 '_GLIBCXX_DEBUG_PEDANTIC',
1115                 'libstdc++ pedantic debug mode'
1116             ),
1117             (os.name != 'nt', 'BOOST_POSIX',
1118                 'Indicates to boost < 1.34 which API to use (posix or windows).'
1119             ),
1120             (os.name != 'nt', 'BOOST_POSIX_API',
1121                 'Indicates to boost 1.34 which API to use (posix or windows).'
1122             ),
1123             (os.name != 'nt', 'BOOST_POSIX_PATH',
1124                 'Indicates to boost 1.34 which path style to use (posix or windows).'
1125             ),
1126             (spell_engine is not None, spell_engine,
1127                 'Spell engine to use'
1128             ),
1129             # we need to know the byte order for unicode conversions
1130             (sys.byteorder == 'big', 'WORDS_BIGENDIAN',
1131                 'Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX).'
1132             ),
1133         ],
1134         extra_items = [
1135             ('#define PACKAGE "%s%s"' % (package, program_suffix),
1136                 'Name of package'),
1137             ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1138                 'Define to the address where bug reports for this package should be sent.'),
1139             ('#define PACKAGE_NAME "%s"' % package_name,
1140                 'Define to the full name of this package.'),
1141             ('#define PACKAGE_STRING "%s"' % package_string,
1142                 'Define to the full name and version of this package.'),
1143             ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1144                 'Define to the one symbol short name of this package.'),
1145             ('#define PACKAGE_VERSION "%s"' % package_version,
1146                 'Define to the version of this package.'),
1147             ('#define BOOST_ALL_NO_LIB 1',
1148                 'disable automatic linking of boost libraries.'),
1149             ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1150                 'Packaging method'),
1151             ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1152                 'Aiksaurus include file'),
1153             ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1154                 "Define to the type of arg 1 for `select'."),
1155             ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1156                 "Define to the type of arg 2, 3, 4 for `select'."),
1157             ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1158                 "Define to the type of arg 5 for `select'."),
1159             ('#define SIZEOF_WCHAR_T %d' % sizeof_wchar_t,
1160                 'Define to be the size of type wchar_t'),
1161         ],
1162         config_post = '''/************************************************************
1163 ** You should not need to change anything beyond this point */
1164
1165 #ifndef HAVE_STRERROR
1166 #if defined(__cplusplus)
1167 extern "C"
1168 #endif
1169 char * strerror(int n);
1170 #endif
1171
1172 #ifdef HAVE_MKSTEMP
1173 #ifndef HAVE_DECL_MKSTEMP
1174 #if defined(__cplusplus)
1175 extern "C"
1176 #endif
1177 int mkstemp(char*);
1178 #endif
1179 #endif
1180
1181 #include <../boost/config.h>
1182
1183 #endif
1184 '''
1185     )
1186
1187     # these keys are needed in env
1188     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1189         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1190         # USE_ASPELL etc does not go through result
1191         if result.has_key(key):
1192             env[key] = result[key]
1193         env_cache[key] = env[key]
1194
1195     #
1196     # if nls=yes and gettext=included, create intl/config.h
1197     # intl/libintl.h etc
1198     #
1199     intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1200     if env['nls'] and included_gettext:
1201         #
1202         print "Creating %s..." % intl_config_h
1203         #
1204         # create intl/config.h
1205         result = utils.createConfigFile(conf,
1206             config_file = intl_config_h,
1207             config_pre = '''/* intl/config.h.  Generated by SCons.  */
1208
1209 /* -*- C++ -*- */
1210 /*
1211 * \file config.h
1212 * This file is part of LyX, the document processor.
1213 * Licence details can be found in the file COPYING.
1214 *
1215 * This is the compilation configuration file for LyX.
1216 * It was generated by scon.
1217 * You might want to change some of the defaults if something goes wrong
1218 * during the compilation.
1219 */
1220
1221 #ifndef _CONFIG_H
1222 #define _CONFIG_H
1223 ''',
1224             headers = [
1225                 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1226                 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1227                 ('string.h', 'HAVE_STRING_H', 'c'),
1228                 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1229                 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1230                 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1231                 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1232                 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1233                 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1234                 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1235             ],
1236             functions = [
1237                 ('getcwd', 'HAVE_GETCWD', None),
1238                 ('stpcpy', 'HAVE_STPCPY', None),
1239                 ('strcasecmp', 'HAVE_STRCASECMP', None),
1240                 ('strdup', 'HAVE_STRDUP', None),
1241                 ('strtoul', 'HAVE_STRTOUL', None),
1242                 ('alloca', 'HAVE_ALLOCA', None),
1243                 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1244                 ('mempcpy', 'HAVE_MEMPCPY', None),
1245                 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1246                 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1247                 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1248                 ('setlocale', 'HAVE_SETLOCALE', None),
1249                 ('tsearch', 'HAVE_TSEARCH', None),
1250                 ('getegid', 'HAVE_GETEGID', None),
1251                 ('getgid', 'HAVE_GETGID', None),
1252                 ('getuid', 'HAVE_GETUID', None),
1253                 ('wcslen', 'HAVE_WCSLEN', None),
1254                 ('asprintf', 'HAVE_ASPRINTF', None),
1255                 ('wprintf', 'HAVE_WPRINTF', None),
1256                 ('snprintf', 'HAVE_SNPRINTF', None),
1257                 ('printf', 'HAVE_POSIX_PRINTF', None),
1258                 ('fcntl', 'HAVE_FCNTL', None),
1259             ],
1260             types = [
1261                 ('intmax_t', 'HAVE_INTMAX_T', None),
1262                 ('long double', 'HAVE_LONG_DOUBLE', None),
1263                 ('long long', 'HAVE_LONG_LONG', None),
1264                 ('wchar_t', 'HAVE_WCHAR_T', None),
1265                 ('wint_t', 'HAVE_WINT_T', None),
1266                 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1267                 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1268             ],
1269             libs = [
1270                 ('c', 'HAVE_LIBC'),
1271             ],
1272             custom_tests = [
1273                 (conf.CheckLC_MESSAGES(),
1274                     'HAVE_LC_MESSAGES',
1275                     'Define if your <locale.h> file defines LC_MESSAGES.'
1276                 ),
1277                 (conf.CheckIconvConst(),
1278                     'ICONV_CONST',
1279                     'Define as const if the declaration of iconv() needs const.',
1280                     '#define ICONV_CONST const',
1281                     '#define ICONV_CONST',
1282                 ),
1283                 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1284                 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1285                     'HAVE_INTMAX_T',
1286                     "Define to 1 if you have the `intmax_t' type."
1287                 ),
1288                 (env.has_key('nls') and env['nls'],
1289                     'ENABLE_NLS',
1290                     "Define to 1 if translation of program messages to the user's native anguage is requested.",
1291                 ),
1292             ],
1293             extra_items = [
1294                 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found'),
1295                 ('#define SIZEOF_WCHAR_T %d' % sizeof_wchar_t,
1296                     'Define to be the size of type wchar_t'),
1297             ],
1298             config_post = '#endif'
1299         )
1300
1301         # these keys are needed in env
1302         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1303             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1304             # USE_ASPELL etc does not go through result
1305             if result.has_key(key):
1306                 env[key] = result[key]
1307             env_cache[key] = env[key]
1308
1309 else:
1310     #
1311     # this comes as a big surprise, without this line
1312     # (doing nothing obvious), adding fast_start=yes
1313     # to a build with fast_start=no will result in a rebuild
1314     # Note that the exact header file to check does not matter
1315     conf.CheckCHeader('io.h')
1316     # only a few variables need to be rescanned
1317     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1318         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1319         env[key] = env_cache[key]
1320     #
1321     # nls related keys
1322     if env['nls'] and included_gettext:
1323         # only a few variables need to be rescanned
1324         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1325             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1326             env[key] = env_cache[key]
1327
1328 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1329 if env['nls'] and included_gettext:
1330     # libgnuintl.h.in => libintl.h
1331     env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1332     env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1333         [Copy('$TARGET', '$SOURCE')])
1334
1335 #
1336 # Finish auto-configuration
1337 env = conf.Finish()
1338
1339 #----------------------------------------------------------
1340 # Now set up our build process accordingly
1341 #----------------------------------------------------------
1342
1343 #
1344 # QT_LIB
1345 #
1346 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1347 # in their respective directory and specialized env.
1348 if frontend == 'qt3':
1349     # note: env.Tool('qt') my set QT_LIB to qt
1350     if platform_name == 'win32':
1351         qt_libs = ['qt-mt3']
1352     else:
1353         qt_libs = ['qt-mt']
1354     frontend_libs = qt_libs
1355 elif frontend == 'qt4':
1356     qt_libs = ['QtCore', 'QtGui']
1357     # set the right lib names
1358     if platform_name == 'win32':
1359         if mode == 'debug' and use_vc:
1360             qt_lib_suffix = 'd4'
1361         else:
1362             qt_lib_suffix = '4'
1363     else:
1364         if mode == 'debug':
1365             qt_lib_suffix = '_debug'
1366         else:
1367             qt_lib_suffix = ''
1368     frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1369
1370
1371 system_libs = env['ICONV_LIB']
1372 if platform_name in ['win32', 'cygwin']:
1373     # the final link step needs stdc++ to succeed under mingw
1374     # FIXME: shouldn't g++ automatically link to stdc++?
1375     if use_vc:
1376         system_libs += ['ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
1377     else:
1378         system_libs += ['shlwapi', 'stdc++', 'z']
1379 elif platform_name == 'cygwin' and env['X11']:
1380     system_libs += ['GL',  'Xmu', 'Xi', 'Xrender', 'Xrandr',
1381         'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 
1382         'resolv', 'pthread', 'z']
1383 else:
1384     system_libs += ['z']
1385
1386 libs = [
1387     ('HAVE_LIBGDI32', 'gdi32'),
1388     ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1389     ('USE_ASPELL', aspell_lib),
1390     ('USE_ISPELL', 'ispell'),
1391     ('USE_PSPELL', 'pspell'),
1392 ]
1393
1394 for lib in libs:
1395     if env[lib[0]]:
1396         system_libs.append(lib[1])
1397
1398 #
1399 # Build parameters CPPPATH etc
1400 #
1401 if env['X11']:
1402     env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1403
1404 #
1405 # boost: for boost header files
1406 # BUILDDIR/common: for config.h
1407 # TOP_SRCDIR/src: for support/* etc
1408 #
1409 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1410 #
1411 # Separating boost directories from CPPPATH stops scons from building
1412 # the dependency tree for boost header files, and effectively reduce
1413 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1414 # boost headers, this is only done for system boost headers.
1415 if included_boost:
1416     env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1417 else:
1418     if use_vc:
1419         env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1420     else:
1421         env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1422
1423 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1424 if env['nls'] and included_gettext:
1425     env['CPPPATH'].append('$BUILDDIR/intl')
1426 #
1427 # QT_INC_PATH is not needed for *every* source file
1428 env['CPPPATH'].remove(qt_inc_path)
1429
1430 #
1431 # A Link script for cygwin see
1432 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1433 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1434 # for details
1435 #
1436 if platform_name == 'cygwin':
1437     ld_script_path = '/tmp'
1438     ld_script = utils.installCygwinLDScript(ld_script_path)
1439     env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1440         '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1441
1442 #
1443 # Report results
1444 #
1445 # fill in the version info
1446 env['VERSION_INFO'] = '''Configuration
1447   Host type:                      %s
1448   Special build flags:            %s
1449   C   Compiler:                   %s
1450   C   Compiler flags:             %s %s
1451   C++ Compiler:                   %s
1452   C++ Compiler LyX flags:         %s
1453   C++ Compiler flags:             %s %s
1454   Linker flags:                   %s
1455   Linker user flags:              %s
1456 Build info:
1457   Builing directory:              %s
1458   Local library directory:        %s
1459   Libraries paths:                %s
1460   Boost libraries:                %s
1461   Frontend libraries:             %s
1462   System libraries:               %s
1463   include search path:            %s
1464 Frontend:
1465   Frontend:                       %s
1466   Packaging:                      %s
1467   LyX dir:                        %s
1468   LyX files dir:                  %s
1469 ''' % (platform_name,
1470     env.subst('$CCFLAGS'), env.subst('$CC'),
1471     env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1472     env.subst('$CXX'), env.subst('$CXXFLAGS'),
1473     env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1474     env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1475     env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1476     str(env['LIBPATH']), str(boost_libraries),
1477     str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1478     frontend, packaging_method,
1479     prefix, env['LYX_DIR'])
1480
1481 if frontend in ['qt3', 'qt4']:
1482     env['VERSION_INFO'] += '''  include dir:                    %s
1483   library dir:                    %s
1484   X11:                            %s
1485 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1486
1487 if not fast_start:
1488     print env['VERSION_INFO']
1489
1490 #
1491 # Mingw command line may be too short for our link usage,
1492 # Here we use a trick from scons wiki
1493 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1494 #
1495 # I also would like to add logging (commands only) capacity to the
1496 # spawn system.
1497 logfile = env.get('logfile', default_log_file)
1498 if logfile != '' or platform_name == 'win32':
1499     import time
1500     utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1501         info = '''# This is a log of commands used by scons to build lyx
1502 # Time: %s
1503 # Command: %s
1504 # Info: %s
1505 ''' % (time.asctime(), ' '.join(sys.argv),
1506     env['VERSION_INFO'].replace('\n','\n# ')) )
1507
1508
1509 # Cleanup stuff
1510 #
1511 # -h will print out help info
1512 Help(opts.GenerateHelpText(env))
1513
1514 # save environment settings (for fast_start option)
1515 cache_file = open(env_cache_file, 'w')
1516 cPickle.dump(env_cache, cache_file)
1517 cache_file.close()
1518
1519
1520 #----------------------------------------------------------
1521 # Start building
1522 #----------------------------------------------------------
1523 # this has been the source of problems on some platforms...
1524 # I find that I need to supply it with full path name
1525 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1526 # this usage needs further investigation.
1527 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1528
1529 print "Building all targets recursively"
1530
1531 if env.has_key('rebuild'):
1532     rebuild_targets = env['rebuild'].split(',')
1533     if 'none' in rebuild_targets or 'no' in rebuild_targets:
1534         rebuild_targets = []
1535     elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1536         # None: let scons decide which components to build
1537         # Forcing all components to be rebuilt is in theory not necessary
1538         rebuild_targets = None    
1539 else:
1540     rebuild_targets = None
1541
1542 def libExists(libname):
1543     ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1544     return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1545
1546 def appExists(apppath, appname):
1547     ''' Check whether or not application already exists'''
1548     return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1549
1550 targets = BUILD_TARGETS
1551 # msvc need to pass full target name, so I have to look for path/lyx etc
1552 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1553     or 'install' in targets or 'all' in targets
1554 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1555 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1556 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1557 build_mathed = build_lyx or 'mathed' in targets
1558 build_insets = build_lyx or 'insets' in targets
1559 build_frontends = build_lyx or 'frontends' in targets
1560 build_graphics = build_lyx or 'graphics' in targets
1561 build_controllers = build_lyx or 'controllers' in targets
1562 build_client = True in ['client' in x for x in targets] \
1563     or 'install' in targets or 'all' in targets
1564 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1565     or 'install' in targets or 'all' in targets
1566 build_lyxbase = build_lyx or 'lyxbase' in targets
1567 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1568 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1569 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1570 build_msvs_projects = use_vc and 'msvs_projects' in targets
1571
1572
1573 # now, if rebuild_targets is specified, do not rebuild some targets
1574 if rebuild_targets is not None:
1575     #
1576     def ifBuildLib(name, libname, old_value):
1577         # explicitly asked to rebuild
1578         if name in rebuild_targets:
1579             return True
1580         # else if not rebuild, and if the library already exists
1581         elif libExists(libname):
1582             return False
1583         # do not change the original value
1584         else:
1585             return old_value
1586     build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1587     build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1588     build_support = ifBuildLib('support', 'support', build_support)
1589     build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1590     build_insets = ifBuildLib('insets', 'insets', build_insets)
1591     build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1592     build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1593     build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1594     build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1595     build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1596     build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1597     #
1598     def ifBuildApp(name, appname, old_value):
1599         # explicitly asked to rebuild
1600         if name in rebuild_targets:
1601             return True
1602         # else if not rebuild, and if the library already exists
1603         elif appExists(name, appname):
1604             return False
1605         # do not change the original value
1606         else:
1607             return old_value
1608     build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1609     build_client = ifBuildApp('client', 'lyxclient', build_client)
1610
1611 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1612 if build_qt3:
1613     frontend = 'qt3'
1614 elif build_qt4:
1615     frontend = 'qt4'
1616
1617
1618 if build_boost:
1619     #
1620     # boost libraries
1621     #
1622     # special builddir
1623     env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1624
1625     boostenv = env.Copy()
1626     #
1627     # boost use its own config.h
1628     boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1629     boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1630
1631     for lib in boost_libs:
1632         print 'Processing files in boost/libs/%s/src...' % lib
1633         boostlib = boostenv.StaticLibrary(
1634             target = '$LOCALLIBPATH/included_boost_%s' % lib,
1635             source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1636         )
1637         Alias('boost', boostlib)
1638
1639
1640 if build_intl:
1641     #
1642     # intl
1643     #
1644     intlenv = env.Copy()
1645
1646     print "Processing files in intl..."
1647
1648     env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1649
1650     # we need the original C compiler for these files
1651     intlenv['CC'] = C_COMPILER
1652     intlenv['CCFLAGS'] = C_CCFLAGS
1653     if use_vc:
1654         intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1655     # intl does not use global config.h
1656     intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1657
1658     intlenv.Append(CCFLAGS = [
1659         r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1660         r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1661         r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1662         '-DIN_LIBINTL',
1663         '-DENABLE_RELOCATABLE=1',
1664         '-DIN_LIBRARY',
1665         r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1666         '-DNO_XMALLOC',
1667         '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1668         '-Drelocate=libintl_relocate',
1669         '-DDEPENDS_ON_LIBICONV=1',
1670         '-DHAVE_CONFIG_H'
1671         ]
1672     )
1673
1674     intl = intlenv.StaticLibrary(
1675         target = '$LOCALLIBPATH/included_intl',
1676         LIBS = ['c'],
1677         source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1678     )
1679     Alias('intl', intl)
1680
1681
1682 #
1683 # Now, src code under src/
1684 #
1685 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1686
1687
1688 if build_support:
1689     #
1690     # src/support
1691     #
1692     print "Processing files in src/support..."
1693
1694     env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1695
1696     support = env.StaticLibrary(
1697         target = '$LOCALLIBPATH/support',
1698         source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1699     )
1700     Alias('support', support)
1701
1702
1703 if build_mathed:
1704     #
1705     # src/mathed
1706     #
1707     print "Processing files in src/mathed..."
1708     #
1709     mathed = env.StaticLibrary(
1710         target = '$LOCALLIBPATH/mathed',
1711         source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1712     )
1713     Alias('mathed', mathed)
1714
1715
1716 if build_insets:
1717     #
1718     # src/insets
1719     #
1720     print "Processing files in src/insets..."
1721     #
1722     insets = env.StaticLibrary(
1723         target = '$LOCALLIBPATH/insets',
1724         source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1725     )
1726     Alias('insets', insets)
1727
1728
1729 if build_frontends:
1730     #
1731     # src/frontends
1732     #
1733     print "Processing files in src/frontends..."
1734
1735     frontends = env.StaticLibrary(
1736         target = '$LOCALLIBPATH/frontends',
1737         source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1738     )
1739     Alias('frontends', frontends)
1740
1741
1742 if build_graphics:
1743     #
1744     # src/graphics
1745     #
1746     print "Processing files in src/graphics..."
1747
1748     graphics = env.StaticLibrary(
1749         target = '$LOCALLIBPATH/graphics',
1750         source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1751     )
1752     Alias('graphics', graphics)
1753
1754
1755 if build_controllers:
1756     #
1757     # src/frontends/controllers
1758     #
1759     print "Processing files in src/frontends/controllers..."
1760
1761     controllers = env.StaticLibrary(
1762         target = '$LOCALLIBPATH/controllers',
1763         source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1764     )
1765     Alias('controllers', controllers)
1766
1767
1768 #
1769 # src/frontend/qt3/4
1770 #
1771 if build_qt3 or build_qt4:
1772     env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1773
1774 if build_qt3:
1775     print "Processing files in src/frontends/qt3..."
1776
1777     qt3env = env.Copy()
1778     # disable auto scan to speed up non build time
1779     qt3env['QT_AUTOSCAN'] = 0
1780     qt3env['QT_MOCHPREFIX'] = ''
1781
1782     # load qt3 tools
1783     qt3env.Tool('qt')
1784
1785     qt3env.AppendUnique(CPPPATH = [
1786         '$BUILDDIR/common',
1787         '$BUILDDIR/common/images',
1788         '$BUILDDIR/common/frontends',
1789         '$BUILDDIR/common/frontends/qt3',
1790         '$BUILDDIR/common/frontends/controllers',
1791         qt_inc_path]
1792     )
1793
1794     qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1795     
1796     # manually moc and uic files for better performance
1797     qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1798
1799     qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1800         src_frontends_qt3_ui_files]
1801
1802     qt3_uiced_cc_files = []
1803     for x in qt3_uiced_files:
1804         qt3_uiced_cc_files.extend(x[1:])
1805
1806     qt3 = qt3env.StaticLibrary(
1807         target = '$LOCALLIBPATH/qt3',
1808         source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1809             + qt3_uiced_cc_files
1810     )
1811     Alias('qt3', qt3)
1812
1813
1814 if build_qt4:
1815     print "Processing files in src/frontends/qt4..."
1816
1817     qt4env = env.Copy()
1818     qt4env['QT_AUTOSCAN'] = 0
1819
1820     # local qt4 toolset from
1821     # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1822     #
1823     # NOTE: I have to patch qt4.py since it does not automatically
1824     # process .C file!!! (add to cxx_suffixes )
1825     #
1826     qt4env.Tool('qt4', [scons_dir])
1827     qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1828
1829     qt4env.AppendUnique(CPPPATH = [
1830         '$BUILDDIR/common',
1831         '$BUILDDIR/common/images',
1832         '$BUILDDIR/common/frontends',
1833         '$BUILDDIR/common/frontends/qt4',
1834         '$BUILDDIR/common/frontends/controllers',
1835         qt_inc_path
1836         ]
1837     )
1838
1839     # FIXME: replace by something from pkg_config
1840     qt4env.Append(CCFLAGS = [
1841         '-DHAVE_CONFIG_H',
1842         '-DQT_CLEAN_NAMESPACE',
1843         '-DQT_GENUINE_STR',
1844         '-DQT_NO_STL',
1845         '-DQT_NO_KEYWORDS',
1846         ]
1847     )
1848
1849
1850     qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1851
1852     #
1853     # Compile resources
1854     #
1855     resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1856         ["$BUILDDIR/common/frontends/qt4/ui/%s" % x for x in src_frontends_qt4_ui_files]]
1857
1858     #
1859     # moc qt4_moc_files, the moced files are included in the original files
1860     #
1861     qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1862
1863     qt4 = qt4env.StaticLibrary(
1864         target = '$LOCALLIBPATH/qt4',
1865         source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1866     )
1867     Alias('qt4', qt4)
1868
1869
1870 if build_client:
1871     #
1872     # src/client
1873     #
1874     env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1875
1876     print "Processing files in src/client..."
1877
1878     if env['HAVE_FCNTL']:
1879         client = env.Program(
1880             target = '$BUILDDIR/common/client/lyxclient',
1881             LIBS = ['support'] + intl_libs + system_libs +
1882                 socket_libs + boost_libraries,
1883             source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1884         )
1885         Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1886             client, [Copy('$TARGET', '$SOURCE')]))
1887     else:
1888         client = None
1889     Alias('client', client)
1890 else:
1891     if env['HAVE_FCNTL']:
1892         # define client even if lyxclient is not built with rebuild=no
1893         client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1894     else:
1895         client = None
1896
1897
1898 if build_tex2lyx:
1899     #
1900     # tex2lyx
1901     #
1902     print "Processing files in src/tex2lyx..."
1903
1904     tex2lyx_env = env.Copy()
1905     #
1906     tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1907     tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1908
1909     for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1910         'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1911         env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1912             [Copy('$TARGET', '$SOURCE')])
1913
1914     tex2lyx = tex2lyx_env.Program(
1915         target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1916         LIBS = ['support'] + boost_libraries + system_libs,
1917         source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1918     )
1919     Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1920         tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1921     Alias('tex2lyx', tex2lyx)
1922 else:
1923     # define tex2lyx even if tex2lyx is not built with rebuild=no
1924     tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1925
1926
1927 if build_lyxbase:
1928     #
1929     # src/
1930     #
1931     print "Processing files in src..."
1932
1933     env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1934
1935     if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1936         src_post_files.append('aspell.C')
1937     elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1938         src_post_files.append('pspell.C')
1939     elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1940         src_post_files.append('ispell.C')
1941
1942     # msvc requires at least one source file with main()
1943     # so I exclude main.C from lyxbase
1944     lyxbase_pre = env.StaticLibrary(
1945         target = '$LOCALLIBPATH/lyxbase_pre',
1946         source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1947     )
1948     lyxbase_post = env.StaticLibrary(
1949         target = '$LOCALLIBPATH/lyxbase_post',
1950         source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1951     )
1952     Alias('lyxbase', lyxbase_pre)
1953     Alias('lyxbase', lyxbase_post)
1954
1955
1956 if build_lyx:
1957     #
1958     # Build lyx with given frontend
1959     #
1960     lyx = env.Program(
1961         target = '$BUILDDIR/$frontend/lyx',
1962         source = ['$BUILDDIR/common/main.C'],
1963         LIBS = [
1964             'lyxbase_pre',
1965             'mathed',
1966             'insets',
1967             'frontends',
1968             frontend,
1969             'controllers',
1970             'graphics',
1971             'support',
1972             'lyxbase_post',
1973             ] +
1974             boost_libraries +
1975             frontend_libs +
1976             intl_libs +
1977             socket_libs +
1978             system_libs
1979     )
1980     # [/path/to/lyx.ext] => lyx-qt3.ext
1981     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1982     Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1983         [Copy('$TARGET', '$SOURCE')]))
1984     Alias('lyx', lyx)
1985 else:
1986     # define lyx even if lyx is not built with rebuild=no
1987     lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1988
1989
1990 if build_msvs_projects:
1991     def build_project(target, full_target = None,
1992         src = [], inc = [], res = [], rebuildTargetOnly = True):
1993         ''' build mavs project files
1994             target:      alias (correspond to directory name)
1995             full_target: full path/filename of the target
1996             src:         source files
1997             inc:         include files
1998             res:         resource files
1999             rebuildTargetOnly:     whether or not only rebuild this target
2000
2001         For non-debug-able targets like static libraries, target (alias) is
2002         enough to build the target. For executable targets, msvs need to know
2003         the full path to start debug them.
2004         '''
2005         if rebuildTargetOnly:
2006             cmds = 'fast_start=yes rebuild='+target
2007         else:
2008             cmds = 'fast_start=yes'
2009         if full_target is None:
2010             build_target = target
2011         else:
2012             build_target = full_target
2013         # project
2014         proj = env.MSVSProject(
2015             target = target + env['MSVSPROJECTSUFFIX'],
2016             # this allows easy access to header files (along with source)
2017             srcs = [env.subst(x) for x in src + inc],
2018             incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2019             localincs = [env.subst(x) for x in inc],
2020             resources = [env.subst(x) for x in res],
2021             buildtarget = build_target,
2022             cmdargs = cmds,
2023             variant = 'Debug'
2024         )
2025         Alias('msvs_projects', proj)
2026     #
2027     boost_src = []
2028     for lib in boost_libs:
2029         boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
2030     build_project('boost', src = boost_src)
2031     #
2032     build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files], 
2033         inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
2034     #
2035     build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
2036         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2037     #
2038     build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
2039         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2040     #
2041     build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files], 
2042         inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
2043     #
2044     build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files], 
2045         inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
2046     #
2047     build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files], 
2048         inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
2049     #
2050     build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files], 
2051         inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
2052     #
2053     build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2054         inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2055         res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
2056     #
2057     build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2058         inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2059         res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
2060     #
2061     build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
2062         inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
2063         rebuildTargetOnly = False,
2064         full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2065     #
2066     build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2067         inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2068         rebuildTargetOnly = False,
2069         full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2070     #
2071     build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2072         inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2073     #
2074     if frontend == 'qt3':
2075         build_project('lyx', 
2076             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2077                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2078                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2079                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2080                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2081                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2082                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2083                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2084             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2085                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2086                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2087                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2088                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2089                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2090                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2091                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2092             res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2093             rebuildTargetOnly = False,
2094             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2095     else:
2096         build_project('lyx', 
2097             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2098                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2099                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2100                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2101                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2102                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2103                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2104                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2105             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2106                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2107                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2108                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2109                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2110                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2111                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2112                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2113             res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2114             rebuildTargetOnly = False,
2115             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2116
2117
2118 if build_po:
2119     #
2120     # po/
2121     #
2122     print 'Processing files in po...'
2123
2124     import glob
2125     # handle po files
2126     #
2127     # files to translate
2128     transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2129     # possibly *only* handle these languages
2130     languages = None
2131     if env.has_key('languages'):
2132         languages = env.make_list(env['lanauges'])
2133     # use defulat msgfmt
2134     gmo_files = []
2135     if not env['MSGFMT']:
2136         print 'msgfmt does not exist. Can not process po files'
2137     else:
2138         # create a builder
2139         env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2140         #
2141         for f in transfiles:
2142             # get filename
2143             fname = os.path.split(f)[1]
2144             # country code
2145             country = fname.split('.')[0]
2146             #
2147             if not languages or country in languages:
2148                 gmo_files.extend(env.Transfiles(f))
2149
2150
2151 if 'install' in targets:
2152     #
2153     # this part is a bit messy right now. Since scons will provide
2154     # --DESTDIR option soon, at least the dest_dir handling can be 
2155     # removed later.
2156     #
2157     # how to join dest_dir and prefix
2158     def joinPaths(path1, path2):
2159         ''' join path1 and path2, do not use os.path.join because
2160             under window, c:\destdir\d:\program is invalid '''
2161         if path1 is None:
2162             return os.path.normpath(path2)
2163         # separate drive letter
2164         (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2165         # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2166         return os.path.join(os.path.normpath(path1), path[1:])
2167     #
2168     # install to dest_dir/prefix
2169     dest_dir = env.get('DESTDIR', None)
2170     dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2171     # create the directory if needed
2172     if not os.path.isdir(dest_prefix_dir):
2173         try:
2174             os.makedirs(dest_prefix_dir)
2175         except:
2176             pass
2177         if not os.path.isdir(dest_prefix_dir):
2178             print 'Can not create directory', dest_prefix_dir
2179             Exit(3)
2180     #
2181     if env.has_key('exec_prefix'):
2182         bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2183     else:
2184         bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2185     if add_suffix:
2186         share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2187     else:
2188         share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2189     man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2190     locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2191     #
2192     import glob
2193     #
2194     # install executables (lyxclient may be None)
2195     #
2196     if add_suffix:
2197         version_suffix = program_suffix
2198     else:
2199         version_suffix = ''
2200     #
2201     # install lyx, if in release mode, try to strip the binary
2202     if env.has_key('STRIP') and env['STRIP'] is not None and mode != 'debug':
2203         # create a builder to strip and install
2204         env['BUILDERS']['StripInstallAs'] = Builder(action='$STRIP $SOURCE -o $TARGET')
2205
2206     # install executables
2207     for (name, obj) in (('lyx', lyx), ('tex2lyx', tex2lyx), ('client', client)):
2208         if obj is None:
2209             continue
2210         target_name = os.path.split(str(obj[0]))[1].replace(name, '%s%s' % (name, version_suffix))
2211         target = os.path.join(bin_dest_dir, target_name)
2212         if env['BUILDERS'].has_key('StripInstallAs'):
2213             env.StripInstallAs(target, obj)
2214         else:
2215             env.InstallAs(target, obj)
2216         Alias('install', target)
2217
2218     # share/lyx
2219     dirs = []
2220     for (dir,files) in [
2221             ('.', lib_files),  
2222             ('clipart', lib_clipart_files),
2223             ('examples', lib_examples_files),
2224             ('images', lib_images_files),
2225             ('images/math', lib_images_math_files),
2226             ('bind', lib_bind_files),
2227             ('kbd', lib_kbd_files),
2228             ('layouts', lib_layouts_files),
2229             ('scripts', lib_scripts_files),
2230             ('templates', lib_templates_files),
2231             ('tex', lib_tex_files),
2232             ('ui', lib_ui_files),
2233             ('doc', lib_doc_files),
2234             ('lyx2lyx', lib_lyx2lyx_files)]:
2235         dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2236             [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2237     Alias('install', dirs)
2238     
2239     if platform_name == 'cygwin':
2240         # cygwin packaging requires a file /usr/share/doc/Cygwin/foot-vendor-suffix.README
2241         Cygwin_README = os.path.join(dest_prefix_dir, 'doc', 'Cygwin', 
2242             '%s%s.README' % (package, package_cygwin_version))
2243         env.InstallAs(Cygwin_README,
2244             os.path.join(env.subst('$TOP_SRCDIR'), 'README.cygwin'))
2245         Alias('install', Cygwin_README)
2246         # also a directory /usr/share/doc/lyx for README etc
2247         Cygwin_Doc = os.path.join(dest_prefix_dir, 'doc', package)
2248         env.Install(Cygwin_Doc, [os.path.join(env.subst('$TOP_SRCDIR'), x) for x in \
2249             ['INSTALL', 'README', 'README.Cygwin', 'RELEASE-NOTES', 'COPYING', 'ANNOUNCE']])
2250         Alias('install', Cygwin_Doc)
2251
2252     # lyx1.4.x does not have lyx2lyx_version.py.in
2253     if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2254         # subst and install this file
2255         env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2256             '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2257         Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2258     # man
2259     env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2260         env.subst('$TOP_SRCDIR/lyx.man'))
2261     env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2262         env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2263     env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2264         env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2265     Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2266         x in ['lyx', 'tex2lyx', 'lyxclient']])
2267     # locale files?
2268     # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2269     for gmo in gmo_files:
2270         lan = os.path.split(str(gmo))[1].split('.')[0]
2271         dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo')
2272         env.InstallAs(dest_file, gmo)
2273         Alias('install', dest_file)
2274
2275
2276 Default('lyx')
2277 Alias('all', ['lyx', 'client', 'tex2lyx'])