]> git.lyx.org Git - features.git/blob - development/scons/SConstruct
97899741e2a2ebdfa45863076ac688da3c84a542
[features.git] / development / scons / SConstruct
1 # vi:filetype=python:expandtab:tabstop=4:shiftwidth=4
2 #
3 # file SConstruct
4 #
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7 #
8 # \author Bo Peng
9 # Full author contact details are available in file CREDITS.
10 #
11 # This is a scons based building system for lyx, please refer
12 # to INSTALL.scons for detailed instructions.
13 #
14
15 import os, sys, copy, cPickle, glob
16
17 # scons_utils.py defines a few utility function
18 sys.path.append('config')
19 import scons_utils as utils
20 # 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'])
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         ],
1104         extra_items = [
1105             ('#define PACKAGE "%s%s"' % (package, program_suffix),
1106                 'Name of package'),
1107             ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1108                 'Define to the address where bug reports for this package should be sent.'),
1109             ('#define PACKAGE_NAME "%s"' % package_name,
1110                 'Define to the full name of this package.'),
1111             ('#define PACKAGE_STRING "%s"' % package_string,
1112                 'Define to the full name and version of this package.'),
1113             ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1114                 'Define to the one symbol short name of this package.'),
1115             ('#define PACKAGE_VERSION "%s"' % package_version,
1116                 'Define to the version of this package.'),
1117             ('#define BOOST_ALL_NO_LIB 1',
1118                 'disable automatic linking of boost libraries.'),
1119             ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1120                 'Packaging method'),
1121             ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1122                 'Aiksaurus include file'),
1123             ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1124                 "Define to the type of arg 1 for `select'."),
1125             ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1126                 "Define to the type of arg 2, 3, 4 for `select'."),
1127             ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1128                 "Define to the type of arg 5 for `select'."),
1129         ],
1130         config_post = '''/************************************************************
1131 ** You should not need to change anything beyond this point */
1132
1133 #ifndef HAVE_STRERROR
1134 #if defined(__cplusplus)
1135 extern "C"
1136 #endif
1137 char * strerror(int n);
1138 #endif
1139
1140 #ifdef HAVE_MKSTEMP
1141 #ifndef HAVE_DECL_MKSTEMP
1142 #if defined(__cplusplus)
1143 extern "C"
1144 #endif
1145 int mkstemp(char*);
1146 #endif
1147 #endif
1148
1149 #include <../boost/config.h>
1150
1151 #endif
1152 '''
1153     )
1154
1155     # these keys are needed in env
1156     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1157         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1158         # USE_ASPELL etc does not go through result
1159         if result.has_key(key):
1160             env[key] = result[key]
1161         env_cache[key] = env[key]
1162
1163     #
1164     # if nls=yes and gettext=included, create intl/config.h
1165     # intl/libintl.h etc
1166     #
1167     intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1168     if env['nls'] and included_gettext:
1169         #
1170         print "Creating %s..." % intl_config_h
1171         #
1172         # create intl/config.h
1173         result = utils.createConfigFile(conf,
1174             config_file = intl_config_h,
1175             config_pre = '''/* intl/config.h.  Generated by SCons.  */
1176
1177 /* -*- C++ -*- */
1178 /*
1179 * \file config.h
1180 * This file is part of LyX, the document processor.
1181 * Licence details can be found in the file COPYING.
1182 *
1183 * This is the compilation configuration file for LyX.
1184 * It was generated by scon.
1185 * You might want to change some of the defaults if something goes wrong
1186 * during the compilation.
1187 */
1188
1189 #ifndef _CONFIG_H
1190 #define _CONFIG_H
1191 ''',
1192             headers = [
1193                 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1194                 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1195                 ('string.h', 'HAVE_STRING_H', 'c'),
1196                 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1197                 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1198                 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1199                 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1200                 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1201                 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1202                 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1203             ],
1204             functions = [
1205                 ('getcwd', 'HAVE_GETCWD', None),
1206                 ('stpcpy', 'HAVE_STPCPY', None),
1207                 ('strcasecmp', 'HAVE_STRCASECMP', None),
1208                 ('strdup', 'HAVE_STRDUP', None),
1209                 ('strtoul', 'HAVE_STRTOUL', None),
1210                 ('alloca', 'HAVE_ALLOCA', None),
1211                 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1212                 ('mempcpy', 'HAVE_MEMPCPY', None),
1213                 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1214                 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1215                 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1216                 ('setlocale', 'HAVE_SETLOCALE', None),
1217                 ('tsearch', 'HAVE_TSEARCH', None),
1218                 ('getegid', 'HAVE_GETEGID', None),
1219                 ('getgid', 'HAVE_GETGID', None),
1220                 ('getuid', 'HAVE_GETUID', None),
1221                 ('wcslen', 'HAVE_WCSLEN', None),
1222                 ('asprintf', 'HAVE_ASPRINTF', None),
1223                 ('wprintf', 'HAVE_WPRINTF', None),
1224                 ('snprintf', 'HAVE_SNPRINTF', None),
1225                 ('printf', 'HAVE_POSIX_PRINTF', None),
1226                 ('fcntl', 'HAVE_FCNTL', None),
1227             ],
1228             types = [
1229                 ('intmax_t', 'HAVE_INTMAX_T', None),
1230                 ('long double', 'HAVE_LONG_DOUBLE', None),
1231                 ('long long', 'HAVE_LONG_LONG', None),
1232                 ('wchar_t', 'HAVE_WCHAR_T', None),
1233                 ('wint_t', 'HAVE_WINT_T', None),
1234                 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1235                 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1236             ],
1237             libs = [
1238                 ('c', 'HAVE_LIBC'),
1239             ],
1240             custom_tests = [
1241                 (conf.CheckLC_MESSAGES(),
1242                     'HAVE_LC_MESSAGES',
1243                     'Define if your <locale.h> file defines LC_MESSAGES.'
1244                 ),
1245                 (conf.CheckIconvConst(),
1246                     'ICONV_CONST',
1247                     'Define as const if the declaration of iconv() needs const.',
1248                     '#define ICONV_CONST const',
1249                     '#define ICONV_CONST',
1250                 ),
1251                 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1252                 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1253                     'HAVE_INTMAX_T',
1254                     "Define to 1 if you have the `intmax_t' type."
1255                 ),
1256                 (env.has_key('nls') and env['nls'],
1257                     'ENABLE_NLS',
1258                     "Define to 1 if translation of program messages to the user's native anguage is requested.",
1259                 ),
1260             ],
1261             extra_items = [
1262                 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found')
1263             ],
1264             config_post = '#endif'
1265         )
1266
1267         # these keys are needed in env
1268         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1269             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1270             # USE_ASPELL etc does not go through result
1271             if result.has_key(key):
1272                 env[key] = result[key]
1273             env_cache[key] = env[key]
1274
1275 else:
1276     #
1277     # this comes as a big surprise, without this line
1278     # (doing nothing obvious), adding fast_start=yes
1279     # to a build with fast_start=no will result in a rebuild
1280     # Note that the exact header file to check does not matter
1281     conf.CheckCHeader('io.h')
1282     # only a few variables need to be rescanned
1283     for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1284         'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1285         env[key] = env_cache[key]
1286     #
1287     # nls related keys
1288     if env['nls'] and included_gettext:
1289         # only a few variables need to be rescanned
1290         for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1291             'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1292             env[key] = env_cache[key]
1293
1294 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1295 if env['nls'] and included_gettext:
1296     # libgnuintl.h.in => libintl.h
1297     env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1298     env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1299         [Copy('$TARGET', '$SOURCE')])
1300
1301 #
1302 # Finish auto-configuration
1303 env = conf.Finish()
1304
1305 #----------------------------------------------------------
1306 # Now set up our build process accordingly
1307 #----------------------------------------------------------
1308
1309 #
1310 # QT_LIB
1311 #
1312 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1313 # in their respective directory and specialized env.
1314 if frontend == 'qt3':
1315     # note: env.Tool('qt') my set QT_LIB to qt
1316     if platform_name == 'win32':
1317         qt_libs = ['qt-mt3']
1318     else:
1319         qt_libs = ['qt-mt']
1320     frontend_libs = qt_libs
1321 elif frontend == 'qt4':
1322     qt_libs = ['QtCore', 'QtGui']
1323     # set the right lib names
1324     if platform_name == 'win32':
1325         if mode == 'debug' and use_vc:
1326             qt_lib_suffix = 'd4'
1327         else:
1328             qt_lib_suffix = '4'
1329     else:
1330         if mode == 'debug':
1331             qt_lib_suffix = '_debug'
1332         else:
1333             qt_lib_suffix = ''
1334     frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1335
1336
1337 if platform_name in ['win32', 'cygwin']:
1338     # the final link step needs stdc++ to succeed under mingw
1339     # FIXME: shouldn't g++ automatically link to stdc++?
1340     if use_vc:
1341         system_libs = [env['ICONV_LIB'], 'ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
1342     else:
1343         system_libs = [env['ICONV_LIB'], 'shlwapi', 'stdc++', 'z']
1344 elif platform_name == 'cygwin' and env['X11']:
1345     system_libs = [env['ICONV_LIB'], 'GL',  'Xmu', 'Xi', 'Xrender', 'Xrandr',
1346         'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 
1347         'resolv', 'pthread', 'z']
1348 else:
1349     system_libs = [env['ICONV_LIB'], 'z']
1350
1351 libs = [
1352     ('HAVE_LIBGDI32', 'gdi32'),
1353     ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1354     ('USE_ASPELL', aspell_lib),
1355     ('USE_ISPELL', 'ispell'),
1356     ('USE_PSPELL', 'pspell'),
1357 ]
1358
1359 for lib in libs:
1360     if env[lib[0]]:
1361         system_libs.append(lib[1])
1362
1363 #
1364 # Build parameters CPPPATH etc
1365 #
1366 if env['X11']:
1367     env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1368
1369 #
1370 # boost: for boost header files
1371 # BUILDDIR/common: for config.h
1372 # TOP_SRCDIR/src: for support/* etc
1373 #
1374 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1375 #
1376 # Separating boost directories from CPPPATH stops scons from building
1377 # the dependency tree for boost header files, and effectively reduce
1378 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1379 # boost headers, this is only done for system boost headers.
1380 if included_boost:
1381     env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1382 else:
1383     if use_vc:
1384         env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1385     else:
1386         env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1387
1388 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1389 if env['nls'] and included_gettext:
1390     env['CPPPATH'].append('$BUILDDIR/intl')
1391 #
1392 # QT_INC_PATH is not needed for *every* source file
1393 env['CPPPATH'].remove(qt_inc_path)
1394
1395 #
1396 # A Link script for cygwin see
1397 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1398 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1399 # for details
1400 #
1401 if platform_name == 'cygwin':
1402     ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1403     ld_script = utils.installCygwinLDScript(ld_script_path)
1404     env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1405         '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1406
1407 #
1408 # Report results
1409 #
1410 # fill in the version info
1411 env['VERSION_INFO'] = '''Configuration
1412   Host type:                      %s
1413   Special build flags:            %s
1414   C   Compiler:                   %s
1415   C   Compiler flags:             %s %s
1416   C++ Compiler:                   %s
1417   C++ Compiler LyX flags:         %s
1418   C++ Compiler flags:             %s %s
1419   Linker flags:                   %s
1420   Linker user flags:              %s
1421 Build info:
1422   Builing directory:              %s
1423   Local library directory:        %s
1424   Libraries paths:                %s
1425   Boost libraries:                %s
1426   Frontend libraries:             %s
1427   System libraries:               %s
1428   include search path:            %s
1429 Frontend:
1430   Frontend:                       %s
1431   Packaging:                      %s
1432   LyX dir:                        %s
1433   LyX files dir:                  %s
1434 ''' % (platform_name,
1435     env.subst('$CCFLAGS'), env.subst('$CC'),
1436     env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1437     env.subst('$CXX'), env.subst('$CXXFLAGS'),
1438     env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1439     env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1440     env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1441     str(env['LIBPATH']), str(boost_libraries),
1442     str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1443     frontend, packaging_method,
1444     prefix, env['LYX_DIR'])
1445
1446 if frontend in ['qt3', 'qt4']:
1447     env['VERSION_INFO'] += '''  include dir:                    %s
1448   library dir:                    %s
1449   X11:                            %s
1450 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1451
1452 if not fast_start:
1453     print env['VERSION_INFO']
1454
1455 #
1456 # Mingw command line may be too short for our link usage,
1457 # Here we use a trick from scons wiki
1458 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1459 #
1460 # I also would like to add logging (commands only) capacity to the
1461 # spawn system.
1462 logfile = env.get('logfile', default_log_file)
1463 if logfile != '' or platform_name == 'win32':
1464     import time
1465     utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1466         info = '''# This is a log of commands used by scons to build lyx
1467 # Time: %s
1468 # Command: %s
1469 # Info: %s
1470 ''' % (time.asctime(), ' '.join(sys.argv),
1471     env['VERSION_INFO'].replace('\n','\n# ')) )
1472
1473
1474 # Cleanup stuff
1475 #
1476 # -h will print out help info
1477 Help(opts.GenerateHelpText(env))
1478
1479 # save environment settings (for fast_start option)
1480 cache_file = open(env_cache_file, 'w')
1481 cPickle.dump(env_cache, cache_file)
1482 cache_file.close()
1483
1484
1485 #----------------------------------------------------------
1486 # Start building
1487 #----------------------------------------------------------
1488 # this has been the source of problems on some platforms...
1489 # I find that I need to supply it with full path name
1490 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1491 # this usage needs further investigation.
1492 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1493
1494 print "Building all targets recursively"
1495
1496 if env.has_key('rebuild'):
1497     rebuild_targets = env['rebuild'].split(',')
1498     if 'none' in rebuild_targets or 'no' in rebuild_targets:
1499         rebuild_targets = []
1500     elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1501         # None: let scons decide which components to build
1502         # Forcing all components to be rebuilt is in theory not necessary
1503         rebuild_targets = None    
1504 else:
1505     rebuild_targets = None
1506
1507 def libExists(libname):
1508     ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1509     return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1510
1511 def appExists(apppath, appname):
1512     ''' Check whether or not application already exists'''
1513     return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1514
1515 targets = BUILD_TARGETS
1516 # msvc need to pass full target name, so I have to look for path/lyx etc
1517 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1518     or 'install' in targets or 'all' in targets
1519 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1520 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1521 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1522 build_mathed = build_lyx or 'mathed' in targets
1523 build_insets = build_lyx or 'insets' in targets
1524 build_frontends = build_lyx or 'frontends' in targets
1525 build_graphics = build_lyx or 'graphics' in targets
1526 build_controllers = build_lyx or 'controllers' in targets
1527 build_client = True in ['client' in x for x in targets] \
1528     or 'install' in targets or 'all' in targets
1529 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1530     or 'install' in targets or 'all' in targets
1531 build_lyxbase = build_lyx or 'lyxbase' in targets
1532 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1533 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1534 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1535 build_msvs_projects = use_vc and 'msvs_projects' in targets
1536
1537
1538 # now, if rebuild_targets is specified, do not rebuild some targets
1539 if rebuild_targets is not None:
1540     #
1541     def ifBuildLib(name, libname, old_value):
1542         # explicitly asked to rebuild
1543         if name in rebuild_targets:
1544             return True
1545         # else if not rebuild, and if the library already exists
1546         elif libExists(libname):
1547             return False
1548         # do not change the original value
1549         else:
1550             return old_value
1551     build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1552     build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1553     build_support = ifBuildLib('support', 'support', build_support)
1554     build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1555     build_insets = ifBuildLib('insets', 'insets', build_insets)
1556     build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1557     build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1558     build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1559     build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1560     build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1561     build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1562     #
1563     def ifBuildApp(name, appname, old_value):
1564         # explicitly asked to rebuild
1565         if name in rebuild_targets:
1566             return True
1567         # else if not rebuild, and if the library already exists
1568         elif appExists(name, appname):
1569             return False
1570         # do not change the original value
1571         else:
1572             return old_value
1573     build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1574     build_client = ifBuildApp('client', 'lyxclient', build_client)
1575
1576 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1577 if build_qt3:
1578     frontend = 'qt3'
1579 elif build_qt4:
1580     frontend = 'qt4'
1581
1582
1583 if build_boost:
1584     #
1585     # boost libraries
1586     #
1587     # special builddir
1588     env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1589
1590     boostenv = env.Copy()
1591     #
1592     # boost use its own config.h
1593     boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1594     boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1595
1596     for lib in boost_libs:
1597         print 'Processing files in boost/libs/%s/src...' % lib
1598         boostlib = boostenv.StaticLibrary(
1599             target = '$LOCALLIBPATH/included_boost_%s' % lib,
1600             source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1601         )
1602         Alias('boost', boostlib)
1603
1604
1605 if build_intl:
1606     #
1607     # intl
1608     #
1609     intlenv = env.Copy()
1610
1611     print "Processing files in intl..."
1612
1613     env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1614
1615     # we need the original C compiler for these files
1616     intlenv['CC'] = C_COMPILER
1617     intlenv['CCFLAGS'] = C_CCFLAGS
1618     if use_vc:
1619         intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1620     # intl does not use global config.h
1621     intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1622
1623     intlenv.Append(CCFLAGS = [
1624         r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1625         r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1626         r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1627         '-DIN_LIBINTL',
1628         '-DENABLE_RELOCATABLE=1',
1629         '-DIN_LIBRARY',
1630         r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1631         '-DNO_XMALLOC',
1632         '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1633         '-Drelocate=libintl_relocate',
1634         '-DDEPENDS_ON_LIBICONV=1',
1635         '-DHAVE_CONFIG_H'
1636         ]
1637     )
1638
1639     intl = intlenv.StaticLibrary(
1640         target = '$LOCALLIBPATH/included_intl',
1641         LIBS = ['c'],
1642         source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1643     )
1644     Alias('intl', intl)
1645
1646
1647 #
1648 # Now, src code under src/
1649 #
1650 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1651
1652
1653 if build_support:
1654     #
1655     # src/support
1656     #
1657     print "Processing files in src/support..."
1658
1659     env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1660
1661     support = env.StaticLibrary(
1662         target = '$LOCALLIBPATH/support',
1663         source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1664     )
1665     Alias('support', support)
1666
1667
1668 if build_mathed:
1669     #
1670     # src/mathed
1671     #
1672     print "Processing files in src/mathed..."
1673     #
1674     mathed = env.StaticLibrary(
1675         target = '$LOCALLIBPATH/mathed',
1676         source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1677     )
1678     Alias('mathed', mathed)
1679
1680
1681 if build_insets:
1682     #
1683     # src/insets
1684     #
1685     print "Processing files in src/insets..."
1686     #
1687     insets = env.StaticLibrary(
1688         target = '$LOCALLIBPATH/insets',
1689         source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1690     )
1691     Alias('insets', insets)
1692
1693
1694 if build_frontends:
1695     #
1696     # src/frontends
1697     #
1698     print "Processing files in src/frontends..."
1699
1700     frontends = env.StaticLibrary(
1701         target = '$LOCALLIBPATH/frontends',
1702         source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1703     )
1704     Alias('frontends', frontends)
1705
1706
1707 if build_graphics:
1708     #
1709     # src/graphics
1710     #
1711     print "Processing files in src/graphics..."
1712
1713     graphics = env.StaticLibrary(
1714         target = '$LOCALLIBPATH/graphics',
1715         source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1716     )
1717     Alias('graphics', graphics)
1718
1719
1720 if build_controllers:
1721     #
1722     # src/frontends/controllers
1723     #
1724     print "Processing files in src/frontends/controllers..."
1725
1726     controllers = env.StaticLibrary(
1727         target = '$LOCALLIBPATH/controllers',
1728         source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1729     )
1730     Alias('controllers', controllers)
1731
1732
1733 #
1734 # src/frontend/qt3/4
1735 #
1736 if build_qt3 or build_qt4:
1737     env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1738
1739 if build_qt3:
1740     print "Processing files in src/frontends/qt3..."
1741
1742     qt3env = env.Copy()
1743     # disable auto scan to speed up non build time
1744     qt3env['QT_AUTOSCAN'] = 0
1745     qt3env['QT_MOCHPREFIX'] = ''
1746
1747     # load qt3 tools
1748     qt3env.Tool('qt')
1749
1750     qt3env.AppendUnique(CPPPATH = [
1751         '$BUILDDIR/common',
1752         '$BUILDDIR/common/images',
1753         '$BUILDDIR/common/frontends',
1754         '$BUILDDIR/common/frontends/qt3',
1755         '$BUILDDIR/common/frontends/controllers',
1756         qt_inc_path]
1757     )
1758
1759     qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1760     
1761     # manually moc and uic files for better performance
1762     qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1763
1764     qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1765         src_frontends_qt3_ui_files]
1766
1767     qt3_uiced_cc_files = []
1768     for x in qt3_uiced_files:
1769         qt3_uiced_cc_files.extend(x[1:])
1770
1771     qt3 = qt3env.StaticLibrary(
1772         target = '$LOCALLIBPATH/qt3',
1773         source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1774             + qt3_uiced_cc_files
1775     )
1776     Alias('qt3', qt3)
1777
1778
1779 if build_qt4:
1780     print "Processing files in src/frontends/qt4..."
1781
1782     qt4env = env.Copy()
1783     qt4env['QT_AUTOSCAN'] = 0
1784
1785     # local qt4 toolset from
1786     # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1787     #
1788     # NOTE: I have to patch qt4.py since it does not automatically
1789     # process .C file!!! (add to cxx_suffixes )
1790     #
1791     qt4env.Tool('qt4', [scons_dir])
1792     qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1793
1794     qt4env.AppendUnique(CPPPATH = [
1795         '$BUILDDIR/common',
1796         '$BUILDDIR/common/images',
1797         '$BUILDDIR/common/frontends',
1798         '$BUILDDIR/common/frontends/qt4',
1799         '$BUILDDIR/common/frontends/controllers',
1800         qt_inc_path
1801         ]
1802     )
1803
1804     # FIXME: replace by something from pkg_config
1805     qt4env.Append(CCFLAGS = [
1806         '-DHAVE_CONFIG_H',
1807         '-DQT_CLEAN_NAMESPACE',
1808         '-DQT_GENUINE_STR',
1809         '-DQT_NO_STL',
1810         '-DQT_NO_KEYWORDS',
1811         ]
1812     )
1813
1814
1815     qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1816
1817     #
1818     # Compile resources
1819     #
1820     resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1821         ["$BUILDDIR/common/frontends/qt4/ui/%s" % x for x in src_frontends_qt4_ui_files]]
1822
1823     #
1824     # moc qt4_moc_files, the moced files are included in the original files
1825     #
1826     qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1827
1828     qt4 = qt4env.StaticLibrary(
1829         target = '$LOCALLIBPATH/qt4',
1830         source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1831     )
1832     Alias('qt4', qt4)
1833
1834
1835 if build_client:
1836     #
1837     # src/client
1838     #
1839     env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1840
1841     print "Processing files in src/client..."
1842
1843     if env['HAVE_FCNTL']:
1844         client = env.Program(
1845             target = '$BUILDDIR/common/client/lyxclient',
1846             LIBS = ['support'] + intl_libs + system_libs +
1847                 socket_libs + boost_libraries,
1848             source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1849         )
1850         Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1851             client, [Copy('$TARGET', '$SOURCE')]))
1852     else:
1853         client = None
1854     Alias('client', client)
1855 else:
1856     if env['HAVE_FCNTL']:
1857         # define client even if lyxclient is not built with rebuild=no
1858         client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1859     else:
1860         client = None
1861
1862
1863 if build_tex2lyx:
1864     #
1865     # tex2lyx
1866     #
1867     print "Processing files in src/tex2lyx..."
1868
1869     tex2lyx_env = env.Copy()
1870     #
1871     tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1872     tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1873
1874     for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1875         'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1876         env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1877             [Copy('$TARGET', '$SOURCE')])
1878
1879     tex2lyx = tex2lyx_env.Program(
1880         target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1881         LIBS = ['support'] + boost_libraries + system_libs,
1882         source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1883     )
1884     Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1885         tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1886     Alias('tex2lyx', tex2lyx)
1887 else:
1888     # define tex2lyx even if tex2lyx is not built with rebuild=no
1889     tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1890
1891
1892 if build_lyxbase:
1893     #
1894     # src/
1895     #
1896     print "Processing files in src..."
1897
1898     env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1899
1900     if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1901         src_post_files.append('aspell.C')
1902     elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1903         src_post_files.append('pspell.C')
1904     elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1905         src_post_files.append('ispell.C')
1906
1907     # msvc requires at least one source file with main()
1908     # so I exclude main.C from lyxbase
1909     lyxbase_pre = env.StaticLibrary(
1910         target = '$LOCALLIBPATH/lyxbase_pre',
1911         source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1912     )
1913     lyxbase_post = env.StaticLibrary(
1914         target = '$LOCALLIBPATH/lyxbase_post',
1915         source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1916     )
1917     Alias('lyxbase', lyxbase_pre)
1918     Alias('lyxbase', lyxbase_post)
1919
1920
1921 if build_lyx:
1922     #
1923     # Build lyx with given frontend
1924     #
1925     lyx = env.Program(
1926         target = '$BUILDDIR/$frontend/lyx',
1927         source = ['$BUILDDIR/common/main.C'],
1928         LIBS = [
1929             'lyxbase_pre',
1930             'mathed',
1931             'insets',
1932             'frontends',
1933             frontend,
1934             'controllers',
1935             'graphics',
1936             'support',
1937             'lyxbase_post',
1938             ] +
1939             boost_libraries +
1940             frontend_libs +
1941             intl_libs +
1942             socket_libs +
1943             system_libs
1944     )
1945     # [/path/to/lyx.ext] => lyx-qt3.ext
1946     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1947     Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1948         [Copy('$TARGET', '$SOURCE')]))
1949     Alias('lyx', lyx)
1950 else:
1951     # define lyx even if lyx is not built with rebuild=no
1952     lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1953
1954
1955 if build_msvs_projects:
1956     def build_project(target, full_target = None,
1957         src = [], inc = [], res = [], rebuildTargetOnly = True):
1958         ''' build mavs project files
1959             target:      alias (correspond to directory name)
1960             full_target: full path/filename of the target
1961             src:         source files
1962             inc:         include files
1963             res:         resource files
1964             rebuildTargetOnly:     whether or not only rebuild this target
1965
1966         For non-debug-able targets like static libraries, target (alias) is
1967         enough to build the target. For executable targets, msvs need to know
1968         the full path to start debug them.
1969         '''
1970         if rebuildTargetOnly:
1971             cmds = 'fast_start=yes rebuild='+target
1972         else:
1973             cmds = 'fast_start=yes'
1974         if full_target is None:
1975             build_target = target
1976         else:
1977             build_target = full_target
1978         # project
1979         proj = env.MSVSProject(
1980             target = target + env['MSVSPROJECTSUFFIX'],
1981             # this allows easy access to header files (along with source)
1982             srcs = [env.subst(x) for x in src + inc],
1983             incs = [env.subst('$TOP_SRCDIR/src/config.h')],
1984             localincs = [env.subst(x) for x in inc],
1985             resources = [env.subst(x) for x in res],
1986             buildtarget = build_target,
1987             cmdargs = cmds,
1988             variant = 'Debug'
1989         )
1990         Alias('msvs_projects', proj)
1991     #
1992     boost_src = []
1993     for lib in boost_libs:
1994         boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1995     build_project('boost', src = boost_src)
1996     #
1997     build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files], 
1998         inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
1999     #
2000     build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
2001         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2002     #
2003     build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files], 
2004         inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2005     #
2006     build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files], 
2007         inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
2008     #
2009     build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files], 
2010         inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
2011     #
2012     build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files], 
2013         inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
2014     #
2015     build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files], 
2016         inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
2017     #
2018     build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2019         inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2020         res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
2021     #
2022     build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2023         inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2024         res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
2025     #
2026     build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
2027         inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
2028         rebuildTargetOnly = False,
2029         full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2030     #
2031     build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2032         inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2033         rebuildTargetOnly = False,
2034         full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2035     #
2036     build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2037         inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2038     #
2039     if frontend == 'qt3':
2040         build_project('lyx', 
2041             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2042                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2043                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2044                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2045                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2046                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2047                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2048                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2049             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2050                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2051                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2052                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2053                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2054                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2055                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2056                 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2057             res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2058             rebuildTargetOnly = False,
2059             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2060     else:
2061         build_project('lyx', 
2062             src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2063                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2064                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2065                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2066                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2067                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2068                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2069                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2070             inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2071                 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2072                 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2073                 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2074                 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2075                 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2076                 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2077                 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2078             res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2079             rebuildTargetOnly = False,
2080             full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2081
2082
2083 if build_po:
2084     #
2085     # po/
2086     #
2087     print 'Processing files in po...'
2088
2089     import glob
2090     # handle po files
2091     #
2092     # files to translate
2093     transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2094     # possibly *only* handle these languages
2095     languages = None
2096     if env.has_key('languages'):
2097         languages = env.make_list(env['lanauges'])
2098     # use defulat msgfmt
2099     gmo_files = []
2100     if not env['MSGFMT']:
2101         print 'msgfmt does not exist. Can not process po files'
2102     else:
2103         # create a builder
2104         env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2105         #
2106         for f in transfiles:
2107             # get filename
2108             fname = os.path.split(f)[1]
2109             # country code
2110             country = fname.split('.')[0]
2111             #
2112             if not languages or country in languages:
2113                 gmo_files.extend(env.Transfiles(f))
2114
2115
2116 if 'install' in targets:
2117     #
2118     # this part is a bit messy right now. Since scons will provide
2119     # --DESTDIR option soon, at least the dest_dir handling can be 
2120     # removed later.
2121     #
2122     # how to join dest_dir and prefix
2123     def joinPaths(path1, path2):
2124         ''' join path1 and path2, do not use os.path.join because
2125             under window, c:\destdir\d:\program is invalid '''
2126         if path1 is None:
2127             return os.path.normpath(path2)
2128         # separate drive letter
2129         (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2130         # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2131         return os.path.join(os.path.normpath(path1), path[1:])
2132     #
2133     # install to dest_dir/prefix
2134     dest_dir = env.get('DESTDIR', None)
2135     dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2136     # create the directory if needed
2137     if not os.path.isdir(dest_prefix_dir):
2138         try:
2139             os.makedirs(dest_prefix_dir)
2140         except:
2141             pass
2142         if not os.path.isdir(dest_prefix_dir):
2143             print 'Can not create directory', dest_prefix_dir
2144             Exit(3)
2145     #
2146     if env.has_key('exec_prefix'):
2147         bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2148     else:
2149         bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2150     if add_suffix:
2151         share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2152     else:
2153         share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2154     man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2155     locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2156     #
2157     import glob
2158     #
2159     # install executables (lyxclient may be None)
2160     #
2161     if add_suffix:
2162         version_suffix = program_suffix
2163     else:
2164         version_suffix = ''
2165     #
2166     # install lyx
2167     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2168     target = os.path.join(bin_dest_dir, target_name)
2169     env.InstallAs(target, lyx)
2170     Alias('install', target)
2171     # install lyx as lyx-qt3
2172     target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2173     target = os.path.join(bin_dest_dir, target_name)
2174     env.InstallAs(target, lyx)
2175     Alias('install', target)
2176     #
2177     # install tex2lyx
2178     target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2179     target = os.path.join(bin_dest_dir, target_name)
2180     env.InstallAs(target, tex2lyx)
2181     Alias('install', target)
2182     #
2183     # install lyxclient, may not exist
2184     if client != None:
2185         target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2186         target = os.path.join(bin_dest_dir, target_name)
2187         env.InstallAs(target, client)
2188         Alias('install', target)
2189     #
2190     # share/lyx
2191     dirs = []
2192     for (dir,files) in [
2193             ('.', lib_files),  
2194             ('clipart', lib_clipart_files),
2195             ('examples', lib_examples_files),
2196             ('images', lib_images_files),
2197             ('images/math', lib_images_math_files),
2198             ('bind', lib_bind_files),
2199             ('kbd', lib_kbd_files),
2200             ('layouts', lib_layouts_files),
2201             ('scripts', lib_scripts_files),
2202             ('templates', lib_templates_files),
2203             ('tex', lib_tex_files),
2204             ('ui', lib_ui_files),
2205             ('doc', lib_doc_files),
2206             ('lyx2lyx', lib_lyx2lyx_files)]:
2207         dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2208             [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2209     
2210     # lyx1.4.x does not have lyx2lyx_version.py.in
2211     if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2212         # subst and install this file
2213         env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2214             '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2215         Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2216     Alias('install', dirs)
2217     # man
2218     env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2219         env.subst('$TOP_SRCDIR/lyx.man'))
2220     env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2221         env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2222     env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2223         env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2224     Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2225         x in ['lyx', 'tex2lyx', 'lyxclient']])
2226     # locale files?
2227     # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2228     for gmo in gmo_files:
2229         lan = os.path.split(str(gmo))[1].split('.')[0]
2230         dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo')
2231         env.InstallAs(dest_file, gmo)
2232         Alias('install', dest_file)
2233
2234
2235 Default('lyx')
2236 Alias('all', ['lyx', 'client', 'tex2lyx'])