1 # vi:filetype=python:expandtab:tabstop=4:shiftwidth=4
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
9 # Full author contact details are available in file CREDITS.
11 # This is a scons based building system for lyx, please refer
12 # to INSTALL.scons for detailed instructions.
15 import os, sys, copy, cPickle, glob
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 *
23 #----------------------------------------------------------
24 # Required runtime environment
25 #----------------------------------------------------------
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."
38 # determine where I am ...
40 # called as 'cd development/scons; scons'
41 if os.path.isfile('SConstruct'):
44 # called as 'scons -f development/scons/SConstruct'
47 scons_dir = 'development/scons'
50 #----------------------------------------------------------
52 #----------------------------------------------------------
54 # some global settings
56 package_version = '1.5.0svn'
57 package_cygwin_version = '1.5.0svn-1'
58 boost_version = '1_33_1'
61 default_build_mode = 'debug'
64 package_bugreport = 'lyx-devel@lists.lyx.org'
66 package_tarname = 'lyx'
67 package_string = '%s %s' % (package_name, package_version)
69 # various cache/log files
70 default_log_file = 'scons_lyx.log'
71 env_cache_file = 'env.cache'
74 #----------------------------------------------------------
75 # platform dependent settings
76 #----------------------------------------------------------
79 platform_name = 'win32'
80 default_frontend = 'qt4'
81 default_prefix = 'c:/program files/lyx'
82 default_with_x = False
83 default_packaging_method = 'windows'
84 elif os.name == 'posix' and sys.platform != 'cygwin':
85 platform_name = sys.platform
86 default_frontend = 'qt3'
87 default_prefix = '/usr/local'
89 default_packaging_method = 'posix'
90 elif os.name == 'posix' and sys.platform == 'cygwin':
91 platform_name = 'cygwin'
92 default_frontend = 'qt3'
93 default_prefix = '/usr'
95 default_packaging_method = 'posix'
96 elif os.name == 'darwin':
97 platform_name = 'macosx'
98 default_frontend = 'qt3'
99 # FIXME: macOSX default prefix?
101 default_with_x = False
102 default_packaging_method = 'macosx'
103 else: # unsupported system, assume posix behavior
104 platform_name = 'others'
105 default_frontend = 'qt3'
107 default_with_x = True
108 default_packaging_method = 'posix'
110 #---------------------------------------------------------
112 #----------------------------------------------------------
114 # You can set perminant default values in config.py
115 if os.path.isfile('config.py'):
116 print "Getting options from config.py..."
117 print open('config.py').read()
119 opts = Options(['config.py'])
122 EnumOption('frontend', 'Main GUI', default_frontend,
123 allowed_values = ('qt3', 'qt4', 'gtk') ),
124 # debug or release build
125 EnumOption('mode', 'Building method', default_build_mode,
126 allowed_values = ('debug', 'release') ),
129 'Use included, system boost library, or try sytem boost first.',
130 'auto', allowed_values = (
131 'auto', # detect boost, if not found, use included
132 'included', # always use included boost
133 'system', # always use system boost, fail if can not find
136 EnumOption('gettext',
137 'Use included, system gettext library, or try sytem gettext first',
138 'auto', allowed_values = (
139 'auto', # detect gettext, if not found, use included
140 'included', # always use included gettext
141 'system', # always use system gettext, fail if can not find
144 EnumOption('spell', 'Choose spell checker to use.', 'auto',
145 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
147 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
148 allowed_values = ('windows', 'posix', 'macosx')),
150 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
151 # No precompiled header support (too troublesome to make it work for msvc)
152 # BoolOption('pch', 'Whether or not use pch', False),
153 # enable assertion, (config.h has ENABLE_ASSERTIOS
154 BoolOption('assertions', 'Use assertions', True),
155 # enable warning, (config.h has WITH_WARNINGS)
156 # default to False since MSVC does not have #warning
157 BoolOption('warnings', 'Use warnings', False),
158 # config.h define _GLIBCXX_CONCEPT_CHECKS
159 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
160 BoolOption('concept_checks', 'Enable concept checks', True),
162 BoolOption('nls', 'Whether or not use native language support', True),
164 BoolOption('profiling', 'Whether or not enable profiling', False),
165 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
166 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
168 BoolOption('X11', 'Use x11 windows system', default_with_x),
169 # use MS VC++ to build lyx
170 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
172 PathOption('qt_dir', 'Path to qt directory', None),
174 PathOption('qt_inc_path', 'Path to qt include directory', None),
176 PathOption('qt_lib_path', 'Path to qt library directory', None),
177 # extra include and libpath
178 PathOption('extra_inc_path', 'Extra include path', None),
180 PathOption('extra_lib_path', 'Extra library path', None),
182 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
184 PathOption('extra_inc_path1', 'Extra include path', None),
186 PathOption('extra_lib_path1', 'Extra library path', None),
187 # rebuild only specifed, comma separated targets
188 ('rebuild', '''rebuild only specifed, comma separated targets.
189 yes or all (default): rebuild everything
190 no or none: rebuild nothing (usually used for installation)
191 comp1,comp2,...: rebuild specified targets''', None),
192 # can be set to a non-existing directory
193 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
194 # build directory, will use $mode if not set
195 ('build_dir', 'Build directory', None),
197 ('version_suffix', 'install lyx as lyx-suffix', None),
198 # how to load options
199 ('load_option', '''load option from previous scons run. option can be
200 yes (default): load all options
201 no: do not load any option
202 opt1,opt2: load specified options
203 -opt1,opt2: load all options other than specified ones''', 'yes'),
205 ('optimization', 'optimization CCFLAGS option.', None),
207 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
209 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
210 # provided for backward compatibility
211 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
212 # environment variable can be set as options.
213 ('DESTDIR', 'install to DESTDIR', None),
214 ('CC', 'replace default $CC', None),
215 ('LINK', 'replace default $LINK', None),
216 ('CPP', 'replace default $CPP', None),
217 ('CXX', 'replace default $CXX', None),
218 ('CXXCPP', 'replace default $CXXCPP', None),
219 ('CCFLAGS', 'replace default $CCFLAGS', None),
220 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
221 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
225 all_options = [x.key for x in opts.options]
227 # copied from SCons/Options/BoolOption.py
228 # We need to use them before a boolean ARGUMENTS option is available
230 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
231 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
233 # whether or not use current config.h, and cached tests
235 # if fast_start=yes (default), load variables from env_cache_file
236 if (not ARGUMENTS.has_key('fast_start') or \
237 ARGUMENTS['fast_start'] in true_strings) \
238 and os.path.isfile(env_cache_file):
240 cache_file = open(env_cache_file)
241 env_cache = cPickle.load(cache_file)
243 print '------------ fast_start mode --------------------'
244 print ' Use cached test results and current config.h'
245 print ' use fast_start=no to override'
251 # if load_option=yes (default), load saved comand line options
253 # This option can take value yes/no/opt1,opt2/-opt1,opt2
254 # and tries to be clever in choosing options to load
255 if (not ARGUMENTS.has_key('load_option') or \
256 ARGUMENTS['load_option'] not in false_strings) \
257 and os.path.isfile(env_cache_file):
258 cache_file = open(env_cache_file)
259 opt_cache = cPickle.load(cache_file)['arg_cache']
261 # import cached options, but we should ignore qt_dir when frontend changes
262 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
263 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
264 and opt_cache.has_key('qt_dir'):
265 opt_cache.pop('qt_dir')
266 # some options will require full rebuild
267 # these are in general things that will change config.h
268 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
269 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
270 ARGUMENTS[arg] != opt_cache[arg]):
272 print " ** fast_start is disabled because of the change of option", arg
275 # and we do not cache some options (dest_dir is obsolete)
276 for arg in ['fast_start', 'load_option', 'dest_dir']:
277 if opt_cache.has_key(arg):
279 # remove obsolete cached keys (well, SConstruct is evolving. :-)
280 for arg in opt_cache.keys():
281 if arg not in all_options:
282 print 'Option %s is obsolete, do not load it' % arg
284 # now, if load_option=opt1,opt2 or -opt1,opt2
285 if ARGUMENTS.has_key('load_option') and \
286 ARGUMENTS['load_option'] not in true_strings + false_strings:
287 # if -opt1,opt2 is specified, do not load these options
288 if ARGUMENTS['load_option'][0] == '-':
289 for arg in ARGUMENTS['load_option'][1:].split(','):
290 if opt_cache.has_key(arg):
292 # if opt1,opt2 is specified, only load specified options
294 args = ARGUMENTS['load_option'].split(',')
295 for arg in opt_cache.keys():
298 # now restore options as if entered from command line
299 for key in opt_cache.keys():
300 if not ARGUMENTS.has_key(key):
301 ARGUMENTS[key] = opt_cache[key]
302 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
305 # check if there is unused (or misspelled) argument
306 for arg in ARGUMENTS.keys():
307 if arg not in all_options:
309 print "Unknown option '%s'... exiting." % arg
311 print "Available options are (check 'scons -help' for details):"
312 print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options)))
316 env_cache['arg_cache'] = ARGUMENTS
319 #---------------------------------------------------------
320 # Setting up environment
321 #---------------------------------------------------------
323 # I do not really like ENV=os.environ, but you may add it
324 # here if you experience some environment related problem
325 env = Environment(options = opts)
327 # set individual variables since I do not really like ENV = os.environ
328 env['ENV']['PATH'] = os.environ.get('PATH')
329 env['ENV']['HOME'] = os.environ.get('HOME')
330 # these are defined for MSVC
331 env['ENV']['LIB'] = os.environ.get('LIB')
332 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
334 # for simplicity, use var instead of env[var]
335 frontend = env['frontend']
336 prefix = env['prefix']
339 if platform_name == 'win32':
340 if env.has_key('use_vc'):
341 use_vc = env['use_vc']
342 if WhereIs('cl.exe') is None:
343 print "cl.exe is not found. Are you using the MSVC environment?"
345 elif WhereIs('cl.exe') is not None:
352 # lyx will be built to $build/build_dir so it is possible
353 # to build multiple build_dirs using the same source
354 # $mode can be debug or release
355 if env.has_key('build_dir') and env['build_dir'] is not None:
356 # create the directory if needed
357 if not os.path.isdir(env['build_dir']):
359 os.makedirs(env['build_dir'])
362 if not os.path.isdir(env['build_dir']):
363 print 'Can not create directory', env['build_dir']
365 env['BUILDDIR'] = env['build_dir']
367 # Determine the name of the build $mode
368 env['BUILDDIR'] = '#' + mode
370 # all built libraries will go to build_dir/libs
371 # (This is different from the make file approach)
372 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
373 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
376 # Here is a summary of variables defined in env
378 # 2. undefined options with a non-None default value
379 # 3. compiler commands and flags like CCFLAGS.
380 # MSGFMT used to process po files
381 # 4. Variables that will be used to replace variables in some_file.in
382 # src/support/package.C.in:
383 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
384 # lib/lyx2lyx/lyx2lyx_version.py.in
387 # PACKAGE_VERSION, VERSION_INFO
389 # full path name is used to build msvs project files
390 # and to replace TOP_SRCDIR in package.C
391 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
392 # needed by src/version.C.in => src/version.C
393 env['PACKAGE_VERSION'] = package_version
395 # determine share_dir etc
396 packaging_method = env.get('packaging')
397 if packaging_method == 'windows':
398 share_dir = 'Resources'
399 man_dir = 'Resources/man/man1'
400 locale_dir = 'Resources/locale'
402 share_dir = 'share/lyx'
403 locale_dir = 'share/locale'
404 if platform_name == 'cygwin':
405 man_dir = 'share/man/man1'
409 # program suffix: can be yes, or a string
410 if env.has_key('version_suffix'):
411 if env['version_suffix'] in true_strings:
412 program_suffix = package_version
413 elif env['version_suffix'] in false_strings:
416 program_suffix = env['version_suffix']
419 # used by package.C.in
420 env['PROGRAM_SUFFIX'] = program_suffix
422 # whether or not add suffix to file and directory names
423 add_suffix = packaging_method != 'windows'
424 # LYX_DIR are different (used in package.C.in)
426 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
428 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
429 # we need absolute path for package.C
430 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
433 #---------------------------------------------------------
434 # Setting building environment (Tools, compiler flags etc)
435 #---------------------------------------------------------
437 # Since Tool('mingw') will reset CCFLAGS etc, this should be
438 # done before getEnvVariable
439 if platform_name == 'win32':
445 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
447 # we differentiate between hard-coded options and default options
448 # hard-coded options are required and will always be there
449 # default options can be replaced by enviromental variables or command line options
450 CCFLAGS_required = []
451 LINKFLAGS_required = []
454 # under windows, scons is confused by .C/.c and uses gcc instead of
455 # g++. I am forcing the use of g++ here. This is expected to change
456 # after lyx renames all .C files to .cpp
458 # save the old c compiler and CCFLAGS (used by libintl)
459 C_COMPILER = env.subst('$CC')
460 C_CCFLAGS = env.subst('$CCFLAGS').split()
461 # if we use ms vc, the commands are fine (cl.exe and link.exe)
463 # /TP treat all source code as C++
464 # C4819: The file contains a character that cannot be represented
465 # in the current code page (number)
466 # C4996: foo was decleared deprecated
467 CCFLAGS_required.extend(['/TP', '/EHsc'])
468 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MD'])
470 if env.has_key('CXX') and env['CXX']:
471 env['CC'] = env.subst('$CXX')
472 env['LINK'] = env.subst('$CXX')
477 # for debug/release mode
478 if env.has_key('optimization') and env['optimization'] is not None:
479 # if user supplies optimization flags, use it anyway
480 CCFLAGS_required.extend(env['optimization'].split())
481 # and do not use default
482 set_default_optimization_flags = False
484 set_default_optimization_flags = True
488 CCFLAGS_required.append('/Zi')
489 LINKFLAGS_required.extend(['/debug', '/map'])
491 CCFLAGS_required.append('-g')
492 CCFLAGS_default.append('-O')
493 elif mode == 'release' and set_default_optimization_flags:
495 CCFLAGS_default.append('/O2')
497 CCFLAGS_default.append('-O2')
499 # msvc uses separate tools for profiling
500 if env.has_key('profiling') and env['profiling']:
502 print 'Visual C++ does not use profiling options'
504 CCFLAGS_required.append('-pg')
505 LINKFLAGS_required.append('-pg')
507 if env.has_key('warnings') and env['warnings']:
509 CCFLAGS_default.append('/W2')
511 # Note: autotools detect gxx version and pass -W for 3.x
512 # and -Wextra for other versions of gcc
513 CCFLAGS_default.append('-Wall')
515 # Now, set the variables as follows:
516 # 1. if command line option exists: replace default
517 # 2. then if s envronment variable exists: replace default
518 # 3. set variable to required + default
519 def setEnvVariable(env, name, required = None, default = None, split = True):
520 ''' env: environment to set variable
522 required: hardcoded options
523 default: default options that can be replaced by command line or
524 environment variables
525 split: whether or not split obtained variable like '-02 -g'
527 # 1. ARGUMENTS is already set to env[name], override default.
528 if ARGUMENTS.has_key(name):
530 # then use environment default
531 elif os.environ.has_key(name):
532 print "Acquiring variable %s from system environment: %s" % (name, os.environ[name])
533 default = os.environ[name]
535 default = default.split()
536 # the real value should be env[name] + default + required
539 if env.has_key(name):
540 value = str(env[name]).split()
541 if required is not None:
543 if default is not None:
547 if env.has_key(name):
548 value = str(env[name])
549 if required is not None:
550 value += " " + required
551 if default is not None:
552 value += " " + default
554 # print name, env[name]
556 setEnvVariable(env, 'DESTDIR', split=False)
557 setEnvVariable(env, 'CC')
558 setEnvVariable(env, 'LINK')
559 setEnvVariable(env, 'CPP')
560 setEnvVariable(env, 'CXX')
561 setEnvVariable(env, 'CXXCPP')
562 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
563 setEnvVariable(env, 'CXXFLAGS')
564 setEnvVariable(env, 'CPPFLAGS')
565 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
567 # if DESTDIR is not set...
568 if env.has_key('dest_dir'):
569 print "This option is obsolete. Please use DESTDIR instead."
570 env['DESTDIR'] = env['dest_dir']
573 #---------------------------------------------------------
574 # Frontend related variables (QTDIR etc)
575 #---------------------------------------------------------
577 if env.has_key('qt_dir') and env['qt_dir']:
578 env['QTDIR'] = env['qt_dir']
579 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
580 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
582 # if there is a valid QTDIR, set path for lib and bin directories
583 if env.has_key('QTDIR'):
584 # add path to the qt tools
585 if os.path.isdir(os.path.join(env['QTDIR'], 'lib')):
586 env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')])
587 # set environment so that moc etc can be found even if its path is not set properly
588 if os.path.isdir(os.path.join(env['QTDIR'], 'bin')):
589 os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin')
590 env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin'))
592 if env.has_key('qt_lib_path') and env['qt_lib_path']:
593 qt_lib_path = env.subst('$qt_lib_path')
594 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
595 qt_lib_path = env.subst('$QTDIR/lib')
596 # this is the path for cygwin.
597 elif os.path.isdir(os.path.join('/usr/lib/', frontend, 'lib')):
598 qt_lib_path = '/usr/lib/%s/lib' % frontend
600 print "Qt library directory is not found. Please specify it using qt_lib_path"
602 env.AppendUnique(LIBPATH = [qt_lib_path])
603 # qt4 seems to be using pkg_config
604 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
606 if env.has_key('qt_inc_path') and env['qt_inc_path']:
607 qt_inc_path = env['qt_inc_path']
608 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
609 qt_inc_path = '$QTDIR/include'
610 # this is the path for cygwin.
611 elif os.path.isdir('/usr/include/' + frontend):
612 qt_inc_path = '/usr/include/' + frontend
614 print "Qt include directory not found. Please specify it using qt_inc_path"
616 # Note that this CPPPATH is for testing only
617 # it will be removed before calling SConscript
618 env['CPPPATH'] = [qt_inc_path]
621 # extra_inc_path and extra_lib_path
624 if env.has_key('extra_inc_path') and env['extra_inc_path']:
625 extra_inc_paths.append(env['extra_inc_path'])
626 if env.has_key('extra_lib_path') and env['extra_lib_path']:
627 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
628 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
629 extra_inc_paths.append(env['extra_inc_path1'])
630 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
631 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
632 if env.has_key('extra_bin_path') and env['extra_bin_path']:
633 # only the first one is needed (a scons bug?)
634 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
635 env.PrependENVPath('PATH', env['extra_bin_path'])
636 # extra_inc_paths will be used later by intlenv etc
637 env.AppendUnique(CPPPATH = extra_inc_paths)
640 #----------------------------------------------------------
642 #----------------------------------------------------------
644 conf = Configure(env,
646 'CheckPkgConfig' : utils.checkPkgConfig,
647 'CheckPackage' : utils.checkPackage,
648 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
649 'CheckSelectArgType' : utils.checkSelectArgType,
650 'CheckBoostLibraries' : utils.checkBoostLibraries,
651 'CheckCommand' : utils.checkCommand,
652 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
653 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
654 'CheckIconvConst' : utils.checkIconvConst,
658 # pkg-config? (if not, we use hard-coded options)
660 if conf.CheckPkgConfig('0.15.0'):
661 env['HAS_PKG_CONFIG'] = True
663 print 'pkg-config >= 0.1.50 is not found'
664 env['HAS_PKG_CONFIG'] = False
665 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
667 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
669 # zlib? This is required. (fast_start assumes the existance of zlib)
671 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
672 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
673 print 'Did not find zdll.lib or zlib.h, exiting!'
675 has_iconv = conf.CheckLib('iconv')
676 has_libiconv = conf.CheckLib('libiconv')
678 env['ICONV_LIB'] = 'iconv'
680 env['ICONV_LIB'] = 'libiconv'
682 print 'Did not find iconv or libiconv, exiting!'
684 env_cache['ICONV_LIB'] = env['ICONV_LIB']
686 env['ICONV_LIB'] = env_cache['ICONV_LIB']
691 # qt3 does not use pkg_config
692 if frontend == 'qt3':
693 # windows lib name is qt-mt3
694 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \
695 and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'):
696 print 'Did not find qt libraries, exiting!'
698 elif frontend == 'qt4':
700 # first: try pkg_config
701 if env['HAS_PKG_CONFIG']:
702 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
703 # FIXME: use pkg_config information?
704 #env['QT4_PKG_CONFIG'] = succ
705 # second: try to link to it
707 # Under linux, I can test the following perfectly
708 # Under windows, lib names need to passed as libXXX4.a ...
709 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
710 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
711 # third: try to look up the path
714 for lib in ['QtCore', 'QtGui']:
715 # windows version has something like QtGui4 ...
716 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
717 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
720 # still can not find it
722 print "Qt4 libraries are found."
724 print 'Did not find qt libraries, exiting!'
727 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
729 if frontend == 'qt3':
730 manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest')
731 elif frontend == 'qt4':
733 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
735 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
736 if os.path.isfile(manifest):
737 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
742 if conf.CheckLib('socket'):
743 socket_libs.append('socket')
744 # nsl is the network services library and provides a
745 # transport-level interface to networking services.
746 if conf.CheckLib('nsl'):
747 socket_libs.append('nsl')
748 env_cache['SOCKET_LIBS'] = socket_libs
750 socket_libs = env_cache['SOCKET_LIBS']
752 # check available boost libs (since lyx1.4 does not use iostream)
754 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
755 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
756 boost_libs.append(lib)
759 # check boost libraries
760 boost_opt = ARGUMENTS.get('boost', 'auto')
761 # check for system boost
762 lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
763 inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
764 # default to $BUILDDIR/libs (use None since this path will be added anyway)
766 # here I assume that all libraries are in the same directory
767 if boost_opt == 'included':
768 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
769 included_boost = True
770 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
771 elif boost_opt == 'auto':
772 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
773 # if not found, use local boost
775 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
776 included_boost = True
777 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
779 included_boost = False
780 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
781 elif boost_opt == 'system':
782 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
784 print "Can not find system boost libraries with version %s " % boost_version
785 print "Please supply a path through extra_lib_path and try again."
786 print "Or use boost=included to use included boost libraries."
789 included_boost = False
790 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
791 env_cache['BOOST_LIBRARIES'] = boost_libraries
792 env_cache['INCLUDED_BOOST'] = included_boost
793 env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
794 env_cache['BOOST_LIBPATH'] = boost_libpath
796 boost_libraries = env_cache['BOOST_LIBRARIES']
797 included_boost = env_cache['INCLUDED_BOOST']
798 env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
799 boost_libpath = env_cache['BOOST_LIBPATH']
801 if boost_libpath is not None:
802 env.AppendUnique(LIBPATH = [boost_libpath])
805 env['ENABLE_NLS'] = env['nls']
808 if not env['ENABLE_NLS']:
810 included_gettext = False
812 # check gettext libraries
813 gettext_opt = ARGUMENTS.get('gettext', 'auto')
814 # check for system gettext
816 if gettext_opt in ['auto', 'system']:
817 if conf.CheckLib('intl'):
818 included_gettext = False
822 if gettext_opt == 'system':
823 print "Can not find system gettext library"
824 print "Please supply a path through extra_lib_path and try again."
825 print "Or use gettext=included to use included gettext libraries."
827 # now, auto and succ = false, or gettext=included
829 # we do not need to set LIBPATH now.
830 included_gettext = True
831 intl_libs = ['included_intl']
832 env_cache['INCLUDED_GETTEXT'] = included_gettext
833 env_cache['INTL_LIBS'] = intl_libs
835 included_gettext = env_cache['INCLUDED_GETTEXT']
836 intl_libs = env_cache['INTL_LIBS']
839 # check for msgfmt command
841 env['MSGFMT'] = conf.CheckCommand('msgfmt')
842 env_cache['MSGFMT'] = env['MSGFMT']
844 env['MSGFMT'] = env_cache['MSGFMT']
846 # cygwin packaging requires the binaries to be stripped
847 if platform_name == 'cygwin':
849 env['STRIP'] = conf.CheckCommand('strip')
850 env_cache['STRIP'] = env['STRIP']
852 env['STRIP'] = env_cache['STRIP']
854 # check uic and moc commands for qt frontends
856 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
857 or conf.CheckCommand('moc') == None):
858 print 'uic or moc command is not found for frontend', frontend
862 # Customized builders
864 # install customized builders
865 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
868 #----------------------------------------------------------
869 # Generating config.h
870 #----------------------------------------------------------
871 aspell_lib = 'aspell'
872 # assume that we use aspell, aspelld compiled for msvc
873 if platform_name == 'win32' and mode == 'debug' and use_vc:
874 aspell_lib = 'aspelld'
876 # check the existence of config.h
877 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
878 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
879 if not fast_start or not os.path.isfile(boost_config_h) \
880 or not os.path.isfile(config_h):
882 print "Creating %s..." % boost_config_h
884 utils.createConfigFile(conf,
885 config_file = boost_config_h,
886 config_pre = '''/* boost/config.h. Generated by SCons. */
891 * This file is part of LyX, the document processor.
892 * Licence details can be found in the file COPYING.
894 * This is the compilation configuration file for LyX.
895 * It was generated by scon.
896 * You might want to change some of the defaults if something goes wrong
897 * during the compilation.
900 #ifndef _BOOST_CONFIG_H
901 #define _BOOST_CONFIG_H
904 ('ostream', 'HAVE_OSTREAM', 'cxx'),
905 ('locale', 'HAVE_LOCALE', 'cxx'),
906 ('sstream', 'HAVE_SSTREAM', 'cxx'),
907 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
910 (env.has_key('assertions') and env['assertions'],
912 'Define if you want assertions to be enabled in the code'
917 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
918 # define USE_BOOST_FORMAT 1
920 # define USE_BOOST_FORMAT 0
923 #if !defined(ENABLE_ASSERTIONS)
924 # define BOOST_DISABLE_ASSERTS 1
926 #define BOOST_ENABLE_ASSERT_HANDLER 1
928 #define BOOST_DISABLE_THREADS 1
929 #define BOOST_NO_WSTRING 1
932 # define BOOST_POSIX 1
935 #define BOOST_ALL_NO_LIB 1
937 #if defined(HAVE_NEWAPIS_H)
938 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
945 print "\nGenerating %s..." % config_h
947 # AIKSAURUS_H_LOCATION
948 if (conf.CheckCXXHeader("Aiksaurus.h")):
949 aik_location = '<Aiksaurus.h>'
950 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
951 aik_location = '<Aiksaurus/Aiksaurus.h>'
955 # determine headers to use
956 spell_opt = ARGUMENTS.get('spell', 'auto')
957 env['USE_ASPELL'] = False
958 env['USE_PSPELL'] = False
959 env['USE_ISPELL'] = False
960 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
961 spell_engine = 'USE_ASPELL'
962 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
963 spell_engine = 'USE_PSPELL'
964 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
965 spell_engine = 'USE_ISPELL'
969 if spell_engine is not None:
970 env[spell_engine] = True
972 if spell_opt == 'auto':
973 print "Warning: Can not locate any spell checker"
974 elif spell_opt != 'no':
975 print "Warning: Can not locate specified spell checker:", spell_opt
978 # check arg types of select function
979 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
983 result = utils.createConfigFile(conf,
984 config_file = config_h,
985 config_pre = '''/* config.h. Generated by SCons. */
990 * This file is part of LyX, the document processor.
991 * Licence details can be found in the file COPYING.
993 * This is the compilation configuration file for LyX.
994 * It was generated by scon.
995 * You might want to change some of the defaults if something goes wrong
996 * during the compilation.
1003 ('io.h', 'HAVE_IO_H', 'c'),
1004 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1005 ('locale.h', 'HAVE_LOCALE_H', 'c'),
1006 ('process.h', 'HAVE_PROCESS_H', 'c'),
1007 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
1008 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
1009 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
1010 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
1011 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
1012 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
1013 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1014 ('utime.h', 'HAVE_UTIME_H', 'c'),
1015 ('direct.h', 'HAVE_DIRECT_H', 'c'),
1016 ('istream', 'HAVE_ISTREAM', 'cxx'),
1017 ('ios', 'HAVE_IOS', 'cxx'),
1020 ('open', 'HAVE_OPEN', None),
1021 ('close', 'HAVE_CLOSE', None),
1022 ('popen', 'HAVE_POPEN', None),
1023 ('pclose', 'HAVE_PCLOSE', None),
1024 ('_open', 'HAVE__OPEN', None),
1025 ('_close', 'HAVE__CLOSE', None),
1026 ('_popen', 'HAVE__POPEN', None),
1027 ('_pclose', 'HAVE__PCLOSE', None),
1028 ('getpid', 'HAVE_GETPID', None),
1029 ('_getpid', 'HAVE__GETPID', None),
1030 ('mkdir', 'HAVE_MKDIR', None),
1031 ('_mkdir', 'HAVE__MKDIR', None),
1032 ('mktemp', 'HAVE_MKTEMP', None),
1033 ('mkstemp', 'HAVE_MKSTEMP', None),
1034 ('strerror', 'HAVE_STRERROR', None),
1035 ('count', 'HAVE_STD_COUNT', '''
1036 #include <algorithm>
1040 return std::count(a, a+5, 'l');
1043 ('getcwd', 'HAVE_GETCWD', None),
1044 ('setenv', 'HAVE_SETENV', None),
1045 ('putenv', 'HAVE_PUTENV', None),
1046 ('fcntl', 'HAVE_FCNTL', None),
1049 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1050 '#include <streambuf>\n#include <istream>')
1053 ('gdi32', 'HAVE_LIBGDI32'),
1054 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1057 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1059 'Define is sys/types.h does not have pid_t',
1061 '#define pid_t int',
1063 (conf.CheckCXXGlobalCstd(),
1065 'Define if your C++ compiler puts C library functions in the global namespace'
1067 (conf.CheckMkdirOneArg(),
1068 'MKDIR_TAKES_ONE_ARG',
1069 'Define if mkdir takes only one argument.'
1071 (conf.CheckIconvConst(),
1073 'Define as const if the declaration of iconv() needs const.',
1074 '#define ICONV_CONST const',
1075 '#define ICONV_CONST',
1077 (conf.CheckLC_MESSAGES(),
1079 'Define if your <locale.h> file defines LC_MESSAGES.'
1081 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1084 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1086 (env['nls'] and not included_gettext,
1088 'Define to 1 if using system gettext library'
1090 (env.has_key('warnings') and env['warnings'],
1092 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1094 (env.has_key('concept_checks') and env['concept_checks'],
1095 '_GLIBCXX_CONCEPT_CHECKS',
1096 'libstdc++ concept checking'
1098 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1100 'libstdc++ debug mode'
1102 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1103 '_GLIBCXX_DEBUG_PEDANTIC',
1104 'libstdc++ pedantic debug mode'
1106 (os.name != 'nt', 'BOOST_POSIX',
1107 'Indicates to boost which API to use (posix or windows).'
1109 (spell_engine is not None, spell_engine,
1110 'Spell engine to use'
1112 # we need to know the byte order for unicode conversions
1113 (sys.byteorder == 'big', 'WORDS_BIGENDIAN',
1114 'Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX).'
1118 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1120 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1121 'Define to the address where bug reports for this package should be sent.'),
1122 ('#define PACKAGE_NAME "%s"' % package_name,
1123 'Define to the full name of this package.'),
1124 ('#define PACKAGE_STRING "%s"' % package_string,
1125 'Define to the full name and version of this package.'),
1126 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1127 'Define to the one symbol short name of this package.'),
1128 ('#define PACKAGE_VERSION "%s"' % package_version,
1129 'Define to the version of this package.'),
1130 ('#define BOOST_ALL_NO_LIB 1',
1131 'disable automatic linking of boost libraries.'),
1132 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1133 'Packaging method'),
1134 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1135 'Aiksaurus include file'),
1136 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1137 "Define to the type of arg 1 for `select'."),
1138 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1139 "Define to the type of arg 2, 3, 4 for `select'."),
1140 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1141 "Define to the type of arg 5 for `select'."),
1143 config_post = '''/************************************************************
1144 ** You should not need to change anything beyond this point */
1146 #ifndef HAVE_STRERROR
1147 #if defined(__cplusplus)
1150 char * strerror(int n);
1154 #ifndef HAVE_DECL_MKSTEMP
1155 #if defined(__cplusplus)
1162 #include <../boost/config.h>
1168 # these keys are needed in env
1169 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1170 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1171 # USE_ASPELL etc does not go through result
1172 if result.has_key(key):
1173 env[key] = result[key]
1174 env_cache[key] = env[key]
1177 # if nls=yes and gettext=included, create intl/config.h
1178 # intl/libintl.h etc
1180 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1181 if env['nls'] and included_gettext:
1183 print "Creating %s..." % intl_config_h
1185 # create intl/config.h
1186 result = utils.createConfigFile(conf,
1187 config_file = intl_config_h,
1188 config_pre = '''/* intl/config.h. Generated by SCons. */
1193 * This file is part of LyX, the document processor.
1194 * Licence details can be found in the file COPYING.
1196 * This is the compilation configuration file for LyX.
1197 * It was generated by scon.
1198 * You might want to change some of the defaults if something goes wrong
1199 * during the compilation.
1206 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1207 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1208 ('string.h', 'HAVE_STRING_H', 'c'),
1209 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1210 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1211 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1212 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1213 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1214 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1215 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1218 ('getcwd', 'HAVE_GETCWD', None),
1219 ('stpcpy', 'HAVE_STPCPY', None),
1220 ('strcasecmp', 'HAVE_STRCASECMP', None),
1221 ('strdup', 'HAVE_STRDUP', None),
1222 ('strtoul', 'HAVE_STRTOUL', None),
1223 ('alloca', 'HAVE_ALLOCA', None),
1224 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1225 ('mempcpy', 'HAVE_MEMPCPY', None),
1226 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1227 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1228 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1229 ('setlocale', 'HAVE_SETLOCALE', None),
1230 ('tsearch', 'HAVE_TSEARCH', None),
1231 ('getegid', 'HAVE_GETEGID', None),
1232 ('getgid', 'HAVE_GETGID', None),
1233 ('getuid', 'HAVE_GETUID', None),
1234 ('wcslen', 'HAVE_WCSLEN', None),
1235 ('asprintf', 'HAVE_ASPRINTF', None),
1236 ('wprintf', 'HAVE_WPRINTF', None),
1237 ('snprintf', 'HAVE_SNPRINTF', None),
1238 ('printf', 'HAVE_POSIX_PRINTF', None),
1239 ('fcntl', 'HAVE_FCNTL', None),
1242 ('intmax_t', 'HAVE_INTMAX_T', None),
1243 ('long double', 'HAVE_LONG_DOUBLE', None),
1244 ('long long', 'HAVE_LONG_LONG', None),
1245 ('wchar_t', 'HAVE_WCHAR_T', None),
1246 ('wint_t', 'HAVE_WINT_T', None),
1247 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1248 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1254 (conf.CheckLC_MESSAGES(),
1256 'Define if your <locale.h> file defines LC_MESSAGES.'
1258 (conf.CheckIconvConst(),
1260 'Define as const if the declaration of iconv() needs const.',
1261 '#define ICONV_CONST const',
1262 '#define ICONV_CONST',
1264 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1265 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1267 "Define to 1 if you have the `intmax_t' type."
1269 (env.has_key('nls') and env['nls'],
1271 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1275 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found')
1277 config_post = '#endif'
1280 # these keys are needed in env
1281 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1282 'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1283 # USE_ASPELL etc does not go through result
1284 if result.has_key(key):
1285 env[key] = result[key]
1286 env_cache[key] = env[key]
1290 # this comes as a big surprise, without this line
1291 # (doing nothing obvious), adding fast_start=yes
1292 # to a build with fast_start=no will result in a rebuild
1293 # Note that the exact header file to check does not matter
1294 conf.CheckCHeader('io.h')
1295 # only a few variables need to be rescanned
1296 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1297 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1298 env[key] = env_cache[key]
1301 if env['nls'] and included_gettext:
1302 # only a few variables need to be rescanned
1303 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1304 'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1305 env[key] = env_cache[key]
1307 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1308 if env['nls'] and included_gettext:
1309 # libgnuintl.h.in => libintl.h
1310 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1311 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1312 [Copy('$TARGET', '$SOURCE')])
1315 # Finish auto-configuration
1318 #----------------------------------------------------------
1319 # Now set up our build process accordingly
1320 #----------------------------------------------------------
1325 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1326 # in their respective directory and specialized env.
1327 if frontend == 'qt3':
1328 # note: env.Tool('qt') my set QT_LIB to qt
1329 if platform_name == 'win32':
1330 qt_libs = ['qt-mt3']
1333 frontend_libs = qt_libs
1334 elif frontend == 'qt4':
1335 qt_libs = ['QtCore', 'QtGui']
1336 # set the right lib names
1337 if platform_name == 'win32':
1338 if mode == 'debug' and use_vc:
1339 qt_lib_suffix = 'd4'
1344 qt_lib_suffix = '_debug'
1347 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1350 if platform_name in ['win32', 'cygwin']:
1351 # the final link step needs stdc++ to succeed under mingw
1352 # FIXME: shouldn't g++ automatically link to stdc++?
1354 system_libs = [env['ICONV_LIB'], 'ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
1356 system_libs = [env['ICONV_LIB'], 'shlwapi', 'stdc++', 'z']
1357 elif platform_name == 'cygwin' and env['X11']:
1358 system_libs = [env['ICONV_LIB'], 'GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr',
1359 'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE',
1360 'resolv', 'pthread', 'z']
1362 system_libs = [env['ICONV_LIB'], 'z']
1365 ('HAVE_LIBGDI32', 'gdi32'),
1366 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1367 ('USE_ASPELL', aspell_lib),
1368 ('USE_ISPELL', 'ispell'),
1369 ('USE_PSPELL', 'pspell'),
1374 system_libs.append(lib[1])
1377 # Build parameters CPPPATH etc
1380 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1383 # boost: for boost header files
1384 # BUILDDIR/common: for config.h
1385 # TOP_SRCDIR/src: for support/* etc
1387 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1389 # Separating boost directories from CPPPATH stops scons from building
1390 # the dependency tree for boost header files, and effectively reduce
1391 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1392 # boost headers, this is only done for system boost headers.
1394 env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1397 env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1399 env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1401 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1402 if env['nls'] and included_gettext:
1403 env['CPPPATH'].append('$BUILDDIR/intl')
1405 # QT_INC_PATH is not needed for *every* source file
1406 env['CPPPATH'].remove(qt_inc_path)
1409 # A Link script for cygwin see
1410 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1411 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1414 if platform_name == 'cygwin':
1415 ld_script_path = '/tmp'
1416 ld_script = utils.installCygwinLDScript(ld_script_path)
1417 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1418 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1423 # fill in the version info
1424 env['VERSION_INFO'] = '''Configuration
1426 Special build flags: %s
1428 C Compiler flags: %s %s
1430 C++ Compiler LyX flags: %s
1431 C++ Compiler flags: %s %s
1433 Linker user flags: %s
1435 Builing directory: %s
1436 Local library directory: %s
1439 Frontend libraries: %s
1440 System libraries: %s
1441 include search path: %s
1447 ''' % (platform_name,
1448 env.subst('$CCFLAGS'), env.subst('$CC'),
1449 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1450 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1451 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1452 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1453 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1454 str(env['LIBPATH']), str(boost_libraries),
1455 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1456 frontend, packaging_method,
1457 prefix, env['LYX_DIR'])
1459 if frontend in ['qt3', 'qt4']:
1460 env['VERSION_INFO'] += ''' include dir: %s
1463 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1466 print env['VERSION_INFO']
1469 # Mingw command line may be too short for our link usage,
1470 # Here we use a trick from scons wiki
1471 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1473 # I also would like to add logging (commands only) capacity to the
1475 logfile = env.get('logfile', default_log_file)
1476 if logfile != '' or platform_name == 'win32':
1478 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1479 info = '''# This is a log of commands used by scons to build lyx
1483 ''' % (time.asctime(), ' '.join(sys.argv),
1484 env['VERSION_INFO'].replace('\n','\n# ')) )
1489 # -h will print out help info
1490 Help(opts.GenerateHelpText(env))
1492 # save environment settings (for fast_start option)
1493 cache_file = open(env_cache_file, 'w')
1494 cPickle.dump(env_cache, cache_file)
1498 #----------------------------------------------------------
1500 #----------------------------------------------------------
1501 # this has been the source of problems on some platforms...
1502 # I find that I need to supply it with full path name
1503 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1504 # this usage needs further investigation.
1505 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1507 print "Building all targets recursively"
1509 if env.has_key('rebuild'):
1510 rebuild_targets = env['rebuild'].split(',')
1511 if 'none' in rebuild_targets or 'no' in rebuild_targets:
1512 rebuild_targets = []
1513 elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1514 # None: let scons decide which components to build
1515 # Forcing all components to be rebuilt is in theory not necessary
1516 rebuild_targets = None
1518 rebuild_targets = None
1520 def libExists(libname):
1521 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1522 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1524 def appExists(apppath, appname):
1525 ''' Check whether or not application already exists'''
1526 return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1528 targets = BUILD_TARGETS
1529 # msvc need to pass full target name, so I have to look for path/lyx etc
1530 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1531 or 'install' in targets or 'all' in targets
1532 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1533 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1534 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1535 build_mathed = build_lyx or 'mathed' in targets
1536 build_insets = build_lyx or 'insets' in targets
1537 build_frontends = build_lyx or 'frontends' in targets
1538 build_graphics = build_lyx or 'graphics' in targets
1539 build_controllers = build_lyx or 'controllers' in targets
1540 build_client = True in ['client' in x for x in targets] \
1541 or 'install' in targets or 'all' in targets
1542 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1543 or 'install' in targets or 'all' in targets
1544 build_lyxbase = build_lyx or 'lyxbase' in targets
1545 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1546 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1547 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1548 build_msvs_projects = use_vc and 'msvs_projects' in targets
1551 # now, if rebuild_targets is specified, do not rebuild some targets
1552 if rebuild_targets is not None:
1554 def ifBuildLib(name, libname, old_value):
1555 # explicitly asked to rebuild
1556 if name in rebuild_targets:
1558 # else if not rebuild, and if the library already exists
1559 elif libExists(libname):
1561 # do not change the original value
1564 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1565 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1566 build_support = ifBuildLib('support', 'support', build_support)
1567 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1568 build_insets = ifBuildLib('insets', 'insets', build_insets)
1569 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1570 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1571 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1572 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1573 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1574 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1576 def ifBuildApp(name, appname, old_value):
1577 # explicitly asked to rebuild
1578 if name in rebuild_targets:
1580 # else if not rebuild, and if the library already exists
1581 elif appExists(name, appname):
1583 # do not change the original value
1586 build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1587 build_client = ifBuildApp('client', 'lyxclient', build_client)
1589 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1601 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1603 boostenv = env.Copy()
1605 # boost use its own config.h
1606 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1607 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1609 for lib in boost_libs:
1610 print 'Processing files in boost/libs/%s/src...' % lib
1611 boostlib = boostenv.StaticLibrary(
1612 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1613 source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1615 Alias('boost', boostlib)
1622 intlenv = env.Copy()
1624 print "Processing files in intl..."
1626 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1628 # we need the original C compiler for these files
1629 intlenv['CC'] = C_COMPILER
1630 intlenv['CCFLAGS'] = C_CCFLAGS
1632 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1633 # intl does not use global config.h
1634 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1636 intlenv.Append(CCFLAGS = [
1637 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1638 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1639 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1641 '-DENABLE_RELOCATABLE=1',
1643 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1645 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1646 '-Drelocate=libintl_relocate',
1647 '-DDEPENDS_ON_LIBICONV=1',
1652 intl = intlenv.StaticLibrary(
1653 target = '$LOCALLIBPATH/included_intl',
1655 source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1661 # Now, src code under src/
1663 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1670 print "Processing files in src/support..."
1672 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1674 support = env.StaticLibrary(
1675 target = '$LOCALLIBPATH/support',
1676 source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1678 Alias('support', support)
1685 print "Processing files in src/mathed..."
1687 mathed = env.StaticLibrary(
1688 target = '$LOCALLIBPATH/mathed',
1689 source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1691 Alias('mathed', mathed)
1698 print "Processing files in src/insets..."
1700 insets = env.StaticLibrary(
1701 target = '$LOCALLIBPATH/insets',
1702 source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1704 Alias('insets', insets)
1711 print "Processing files in src/frontends..."
1713 frontends = env.StaticLibrary(
1714 target = '$LOCALLIBPATH/frontends',
1715 source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1717 Alias('frontends', frontends)
1724 print "Processing files in src/graphics..."
1726 graphics = env.StaticLibrary(
1727 target = '$LOCALLIBPATH/graphics',
1728 source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1730 Alias('graphics', graphics)
1733 if build_controllers:
1735 # src/frontends/controllers
1737 print "Processing files in src/frontends/controllers..."
1739 controllers = env.StaticLibrary(
1740 target = '$LOCALLIBPATH/controllers',
1741 source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1743 Alias('controllers', controllers)
1747 # src/frontend/qt3/4
1749 if build_qt3 or build_qt4:
1750 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1753 print "Processing files in src/frontends/qt3..."
1756 # disable auto scan to speed up non build time
1757 qt3env['QT_AUTOSCAN'] = 0
1758 qt3env['QT_MOCHPREFIX'] = ''
1763 qt3env.AppendUnique(CPPPATH = [
1765 '$BUILDDIR/common/images',
1766 '$BUILDDIR/common/frontends',
1767 '$BUILDDIR/common/frontends/qt3',
1768 '$BUILDDIR/common/frontends/controllers',
1772 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1774 # manually moc and uic files for better performance
1775 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1777 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1778 src_frontends_qt3_ui_files]
1780 qt3_uiced_cc_files = []
1781 for x in qt3_uiced_files:
1782 qt3_uiced_cc_files.extend(x[1:])
1784 qt3 = qt3env.StaticLibrary(
1785 target = '$LOCALLIBPATH/qt3',
1786 source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1787 + qt3_uiced_cc_files
1793 print "Processing files in src/frontends/qt4..."
1796 qt4env['QT_AUTOSCAN'] = 0
1798 # local qt4 toolset from
1799 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1801 # NOTE: I have to patch qt4.py since it does not automatically
1802 # process .C file!!! (add to cxx_suffixes )
1804 qt4env.Tool('qt4', [scons_dir])
1805 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1807 qt4env.AppendUnique(CPPPATH = [
1809 '$BUILDDIR/common/images',
1810 '$BUILDDIR/common/frontends',
1811 '$BUILDDIR/common/frontends/qt4',
1812 '$BUILDDIR/common/frontends/controllers',
1817 # FIXME: replace by something from pkg_config
1818 qt4env.Append(CCFLAGS = [
1820 '-DQT_CLEAN_NAMESPACE',
1828 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1833 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1834 ["$BUILDDIR/common/frontends/qt4/ui/%s" % x for x in src_frontends_qt4_ui_files]]
1837 # moc qt4_moc_files, the moced files are included in the original files
1839 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1841 qt4 = qt4env.StaticLibrary(
1842 target = '$LOCALLIBPATH/qt4',
1843 source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1852 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1854 print "Processing files in src/client..."
1856 if env['HAVE_FCNTL']:
1857 client = env.Program(
1858 target = '$BUILDDIR/common/client/lyxclient',
1859 LIBS = ['support'] + intl_libs + system_libs +
1860 socket_libs + boost_libraries,
1861 source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1863 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1864 client, [Copy('$TARGET', '$SOURCE')]))
1867 Alias('client', client)
1869 if env['HAVE_FCNTL']:
1870 # define client even if lyxclient is not built with rebuild=no
1871 client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1880 print "Processing files in src/tex2lyx..."
1882 tex2lyx_env = env.Copy()
1884 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1885 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1887 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1888 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1889 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1890 [Copy('$TARGET', '$SOURCE')])
1892 tex2lyx = tex2lyx_env.Program(
1893 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1894 LIBS = ['support'] + boost_libraries + system_libs,
1895 source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1897 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1898 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1899 Alias('tex2lyx', tex2lyx)
1901 # define tex2lyx even if tex2lyx is not built with rebuild=no
1902 tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1909 print "Processing files in src..."
1911 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1913 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1914 src_post_files.append('aspell.C')
1915 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1916 src_post_files.append('pspell.C')
1917 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1918 src_post_files.append('ispell.C')
1920 # msvc requires at least one source file with main()
1921 # so I exclude main.C from lyxbase
1922 lyxbase_pre = env.StaticLibrary(
1923 target = '$LOCALLIBPATH/lyxbase_pre',
1924 source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1926 lyxbase_post = env.StaticLibrary(
1927 target = '$LOCALLIBPATH/lyxbase_post',
1928 source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1930 Alias('lyxbase', lyxbase_pre)
1931 Alias('lyxbase', lyxbase_post)
1936 # Build lyx with given frontend
1939 target = '$BUILDDIR/$frontend/lyx',
1940 source = ['$BUILDDIR/common/main.C'],
1958 # [/path/to/lyx.ext] => lyx-qt3.ext
1959 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1960 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1961 [Copy('$TARGET', '$SOURCE')]))
1964 # define lyx even if lyx is not built with rebuild=no
1965 lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1968 if build_msvs_projects:
1969 def build_project(target, full_target = None,
1970 src = [], inc = [], res = [], rebuildTargetOnly = True):
1971 ''' build mavs project files
1972 target: alias (correspond to directory name)
1973 full_target: full path/filename of the target
1977 rebuildTargetOnly: whether or not only rebuild this target
1979 For non-debug-able targets like static libraries, target (alias) is
1980 enough to build the target. For executable targets, msvs need to know
1981 the full path to start debug them.
1983 if rebuildTargetOnly:
1984 cmds = 'fast_start=yes rebuild='+target
1986 cmds = 'fast_start=yes'
1987 if full_target is None:
1988 build_target = target
1990 build_target = full_target
1992 proj = env.MSVSProject(
1993 target = target + env['MSVSPROJECTSUFFIX'],
1994 # this allows easy access to header files (along with source)
1995 srcs = [env.subst(x) for x in src + inc],
1996 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
1997 localincs = [env.subst(x) for x in inc],
1998 resources = [env.subst(x) for x in res],
1999 buildtarget = build_target,
2003 Alias('msvs_projects', proj)
2006 for lib in boost_libs:
2007 boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
2008 build_project('boost', src = boost_src)
2010 build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files],
2011 inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
2013 build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
2014 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2016 build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
2017 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2019 build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files],
2020 inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
2022 build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files],
2023 inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
2025 build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files],
2026 inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
2028 build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files],
2029 inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
2031 build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2032 inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2033 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
2035 build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2036 inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2037 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
2039 build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
2040 inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
2041 rebuildTargetOnly = False,
2042 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2044 build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2045 inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2046 rebuildTargetOnly = False,
2047 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2049 build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2050 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2052 if frontend == 'qt3':
2053 build_project('lyx',
2054 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2055 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2056 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2057 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2058 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2059 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2060 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2061 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2062 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2063 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2064 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2065 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2066 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2067 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2068 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2069 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2070 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2071 rebuildTargetOnly = False,
2072 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2074 build_project('lyx',
2075 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2076 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2077 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2078 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2079 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2080 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2081 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2082 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2083 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2084 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2085 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2086 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2087 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2088 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2089 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2090 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2091 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2092 rebuildTargetOnly = False,
2093 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2100 print 'Processing files in po...'
2105 # files to translate
2106 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2107 # possibly *only* handle these languages
2109 if env.has_key('languages'):
2110 languages = env.make_list(env['lanauges'])
2111 # use defulat msgfmt
2113 if not env['MSGFMT']:
2114 print 'msgfmt does not exist. Can not process po files'
2117 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2119 for f in transfiles:
2121 fname = os.path.split(f)[1]
2123 country = fname.split('.')[0]
2125 if not languages or country in languages:
2126 gmo_files.extend(env.Transfiles(f))
2129 if 'install' in targets:
2131 # this part is a bit messy right now. Since scons will provide
2132 # --DESTDIR option soon, at least the dest_dir handling can be
2135 # how to join dest_dir and prefix
2136 def joinPaths(path1, path2):
2137 ''' join path1 and path2, do not use os.path.join because
2138 under window, c:\destdir\d:\program is invalid '''
2140 return os.path.normpath(path2)
2141 # separate drive letter
2142 (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2143 # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2144 return os.path.join(os.path.normpath(path1), path[1:])
2146 # install to dest_dir/prefix
2147 dest_dir = env.get('DESTDIR', None)
2148 dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2149 # create the directory if needed
2150 if not os.path.isdir(dest_prefix_dir):
2152 os.makedirs(dest_prefix_dir)
2155 if not os.path.isdir(dest_prefix_dir):
2156 print 'Can not create directory', dest_prefix_dir
2159 if env.has_key('exec_prefix'):
2160 bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2162 bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2164 share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2166 share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2167 man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2168 locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2172 # install executables (lyxclient may be None)
2175 version_suffix = program_suffix
2179 # install lyx, if in release mode, try to strip the binary
2180 if env.has_key('STRIP') and env['STRIP'] is not None and mode != 'debug':
2181 # create a builder to strip and install
2182 env['BUILDERS']['StripInstallAs'] = Builder(action='$STRIP $SOURCE -o $TARGET')
2184 # install executables
2185 for (name, obj) in (('lyx', lyx), ('tex2lyx', tex2lyx), ('client', client)):
2188 target_name = os.path.split(str(obj[0]))[1].replace(name, '%s%s' % (name, version_suffix))
2189 target = os.path.join(bin_dest_dir, target_name)
2190 if env['BUILDERS'].has_key('StripInstallAs'):
2191 env.StripInstallAs(target, obj)
2193 env.InstallAs(target, obj)
2194 Alias('install', target)
2198 for (dir,files) in [
2200 ('clipart', lib_clipart_files),
2201 ('examples', lib_examples_files),
2202 ('images', lib_images_files),
2203 ('images/math', lib_images_math_files),
2204 ('bind', lib_bind_files),
2205 ('kbd', lib_kbd_files),
2206 ('layouts', lib_layouts_files),
2207 ('scripts', lib_scripts_files),
2208 ('templates', lib_templates_files),
2209 ('tex', lib_tex_files),
2210 ('ui', lib_ui_files),
2211 ('doc', lib_doc_files),
2212 ('lyx2lyx', lib_lyx2lyx_files)]:
2213 dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2214 [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2215 Alias('install', dirs)
2217 if platform_name == 'cygwin':
2218 # cygwin packaging requires a file /usr/share/doc/Cygwin/foot-vendor-suffix.README
2219 Cygwin_README = os.path.join(dest_prefix_dir, 'doc', 'Cygwin',
2220 '%s%s.README' % (package, package_cygwin_version))
2221 env.InstallAs(Cygwin_README,
2222 os.path.join(env.subst('$TOP_SRCDIR'), 'README.cygwin'))
2223 Alias('install', Cygwin_README)
2224 # also a directory /usr/share/doc/lyx for README etc
2225 Cygwin_Doc = os.path.join(dest_prefix_dir, 'doc', package)
2226 env.Install(Cygwin_Doc, [os.path.join(env.subst('$TOP_SRCDIR'), x) for x in \
2227 ['INSTALL', 'README', 'README.Cygwin', 'RELEASE-NOTES', 'COPYING', 'ANNOUNCE']])
2228 Alias('install', Cygwin_Doc)
2230 # lyx1.4.x does not have lyx2lyx_version.py.in
2231 if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2232 # subst and install this file
2233 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2234 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2235 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2237 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2238 env.subst('$TOP_SRCDIR/lyx.man'))
2239 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2240 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2241 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2242 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2243 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2244 x in ['lyx', 'tex2lyx', 'lyxclient']])
2246 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2247 for gmo in gmo_files:
2248 lan = os.path.split(str(gmo))[1].split('.')[0]
2249 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo')
2250 env.InstallAs(dest_file, gmo)
2251 Alias('install', dest_file)
2255 Alias('all', ['lyx', 'client', 'tex2lyx'])