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