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