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 boost_version = '1_33_1'
60 default_build_mode = 'debug'
63 package_bugreport = 'lyx-devel@lists.lyx.org'
65 package_tarname = 'lyx'
66 package_string = '%s %s' % (package_name, package_version)
68 # various cache/log files
69 default_log_file = 'scons_lyx.log'
70 env_cache_file = 'env.cache'
73 #----------------------------------------------------------
74 # platform dependent settings
75 #----------------------------------------------------------
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'
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'
94 default_packaging_method = 'posix'
95 elif os.name == 'darwin':
96 platform_name = 'macosx'
97 default_frontend = 'qt3'
98 # FIXME: macOSX 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'
106 default_with_x = True
107 default_packaging_method = 'posix'
109 #---------------------------------------------------------
111 #----------------------------------------------------------
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()
118 opts = Options(['config.py'])
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') ),
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
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
143 EnumOption('spell', 'Choose spell checker to use.', 'auto',
144 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
146 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
147 allowed_values = ('windows', 'posix', 'macosx')),
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),
161 BoolOption('nls', 'Whether or not use native language support', True),
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),
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),
171 PathOption('qt_dir', 'Path to qt directory', None),
173 PathOption('qt_inc_path', 'Path to qt include directory', None),
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),
179 PathOption('extra_lib_path', 'Extra library path', None),
181 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
183 PathOption('extra_inc_path1', 'Extra include path', None),
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),
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'),
204 ('optimization', 'optimization CCFLAGS option.', None),
206 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
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),
224 all_options = [x.key for x in opts.options]
226 # copied from SCons/Options/BoolOption.py
227 # We need to use them before a boolean ARGUMENTS option is available
229 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
230 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
232 # whether or not use current config.h, and cached tests
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):
239 cache_file = open(env_cache_file)
240 env_cache = cPickle.load(cache_file)
242 print '------------ fast_start mode --------------------'
243 print ' Use cached test results and current config.h'
244 print ' use fast_start=no to override'
250 # if load_option=yes (default), load saved comand line options
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']
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]):
271 print " ** fast_start is disabled because of the change of option", arg
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):
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
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):
291 # if opt1,opt2 is specified, only load specified options
293 args = ARGUMENTS['load_option'].split(',')
294 for arg in opt_cache.keys():
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])
304 # check if there is unused (or misspelled) argument
305 for arg in ARGUMENTS.keys():
306 if arg not in all_options:
308 print "Unknown option '%s'... exiting." % arg
310 print "Available options are (check 'scons -help' for details):"
311 print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options)))
315 env_cache['arg_cache'] = ARGUMENTS
318 #---------------------------------------------------------
319 # Setting up environment
320 #---------------------------------------------------------
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)
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')
333 # for simplicity, use var instead of env[var]
334 frontend = env['frontend']
335 prefix = env['prefix']
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?"
344 elif WhereIs('cl.exe') is not None:
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']):
358 os.makedirs(env['build_dir'])
361 if not os.path.isdir(env['build_dir']):
362 print 'Can not create directory', env['build_dir']
364 env['BUILDDIR'] = env['build_dir']
366 # Determine the name of the build $mode
367 env['BUILDDIR'] = '#' + mode
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'])
375 # Here is a summary of variables defined in env
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
386 # PACKAGE_VERSION, VERSION_INFO
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
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'
402 share_dir = 'share/lyx'
404 locale_dir = 'share/locale'
405 default_prefix = '/usr/local/'
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:
415 program_suffix = env['version_suffix']
418 # used by package.C.in
419 env['PROGRAM_SUFFIX'] = program_suffix
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)
425 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
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
432 #---------------------------------------------------------
433 # Setting building environment (Tools, compiler flags etc)
434 #---------------------------------------------------------
436 # Since Tool('mingw') will reset CCFLAGS etc, this should be
437 # done before getEnvVariable
438 if platform_name == 'win32':
444 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
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 = []
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
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)
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'])
469 if env.has_key('CXX') and env['CXX']:
470 env['CC'] = env.subst('$CXX')
471 env['LINK'] = env.subst('$CXX')
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
483 set_default_optimization_flags = True
487 CCFLAGS_required.append('/Zi')
488 LINKFLAGS_required.extend(['/debug', '/map'])
490 CCFLAGS_required.append('-g')
491 CCFLAGS_default.append('-O')
492 elif mode == 'release' and set_default_optimization_flags:
494 CCFLAGS_default.append('/O2')
496 CCFLAGS_default.append('-O2')
498 # msvc uses separate tools for profiling
499 if env.has_key('profiling') and env['profiling']:
501 print 'Visual C++ does not use profiling options'
503 CCFLAGS_required.append('-pg')
504 LINKFLAGS_required.append('-pg')
506 if env.has_key('warnings') and env['warnings']:
508 CCFLAGS_default.append('/W2')
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')
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
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'
526 # 1. ARGUMENTS is already set to env[name], override default.
527 if ARGUMENTS.has_key(name):
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]
534 default = default.split()
535 # the real value should be env[name] + default + required
538 if env.has_key(name):
539 value = str(env[name]).split()
540 if required is not None:
542 if default is not None:
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
553 # print name, env[name]
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)
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']
572 #---------------------------------------------------------
573 # Frontend related variables (QTDIR etc)
574 #---------------------------------------------------------
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')
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'))
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
599 print "Qt library directory is not found. Please specify it using qt_lib_path"
601 env.AppendUnique(LIBPATH = [qt_lib_path])
602 # qt4 seems to be using pkg_config
603 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
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
613 print "Qt include directory not found. Please specify it using qt_inc_path"
615 # Note that this CPPPATH is for testing only
616 # it will be removed before calling SConscript
617 env['CPPPATH'] = [qt_inc_path]
620 # extra_inc_path and extra_lib_path
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)
639 #----------------------------------------------------------
641 #----------------------------------------------------------
643 conf = Configure(env,
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,
657 # pkg-config? (if not, we use hard-coded options)
659 if conf.CheckPkgConfig('0.15.0'):
660 env['HAS_PKG_CONFIG'] = True
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']
666 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
668 # zlib? This is required. (fast_start assumes the existance of zlib)
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!'
674 has_iconv = conf.CheckLib('iconv')
675 has_libiconv = conf.CheckLib('libiconv')
677 env['ICONV_LIB'] = 'iconv'
679 env['ICONV_LIB'] = 'libiconv'
681 print 'Did not find iconv or libiconv, exiting!'
683 env_cache['ICONV_LIB'] = env['ICONV_LIB']
685 env['ICONV_LIB'] = env_cache['ICONV_LIB']
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!'
697 elif frontend == 'qt4':
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
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
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))):
719 # still can not find it
721 print "Qt4 libraries are found."
723 print 'Did not find qt libraries, exiting!'
726 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
728 if frontend == 'qt3':
729 manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest')
730 elif frontend == 'qt4':
732 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
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]
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
749 socket_libs = env_cache['SOCKET_LIBS']
751 # check available boost libs (since lyx1.4 does not use iostream)
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)
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)
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
774 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
775 included_boost = True
776 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
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')
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."
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
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']
800 if boost_libpath is not None:
801 env.AppendUnique(LIBPATH = [boost_libpath])
804 env['ENABLE_NLS'] = env['nls']
807 if not env['ENABLE_NLS']:
809 included_gettext = False
811 # check gettext libraries
812 gettext_opt = ARGUMENTS.get('gettext', 'auto')
813 # check for system gettext
815 if gettext_opt in ['auto', 'system']:
816 if conf.CheckLib('intl'):
817 included_gettext = False
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."
826 # now, auto and succ = false, or gettext=included
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
834 included_gettext = env_cache['INCLUDED_GETTEXT']
835 intl_libs = env_cache['INTL_LIBS']
838 # check for msgfmt command
840 env['MSGFMT'] = conf.CheckCommand('msgfmt')
841 env_cache['MSGFMT'] = env['MSGFMT']
843 env['MSGFMT'] = env_cache['MSGFMT']
845 # check uic and moc commands for qt frontends
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
853 # Customized builders
855 # install customized builders
856 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
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'
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):
873 print "Creating %s..." % boost_config_h
875 utils.createConfigFile(conf,
876 config_file = boost_config_h,
877 config_pre = '''/* boost/config.h. Generated by SCons. */
882 * This file is part of LyX, the document processor.
883 * Licence details can be found in the file COPYING.
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.
891 #ifndef _BOOST_CONFIG_H
892 #define _BOOST_CONFIG_H
895 ('ostream', 'HAVE_OSTREAM', 'cxx'),
896 ('locale', 'HAVE_LOCALE', 'cxx'),
897 ('sstream', 'HAVE_SSTREAM', 'cxx'),
898 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
901 (env.has_key('assertions') and env['assertions'],
903 'Define if you want assertions to be enabled in the code'
908 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
909 # define USE_BOOST_FORMAT 1
911 # define USE_BOOST_FORMAT 0
914 #if !defined(ENABLE_ASSERTIONS)
915 # define BOOST_DISABLE_ASSERTS 1
917 #define BOOST_ENABLE_ASSERT_HANDLER 1
919 #define BOOST_DISABLE_THREADS 1
920 #define BOOST_NO_WSTRING 1
923 # define BOOST_POSIX 1
926 #define BOOST_ALL_NO_LIB 1
928 #if defined(HAVE_NEWAPIS_H)
929 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
936 print "\nGenerating %s..." % config_h
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>'
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'
960 if spell_engine is not None:
961 env[spell_engine] = True
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
969 # check arg types of select function
970 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
974 result = utils.createConfigFile(conf,
975 config_file = config_h,
976 config_pre = '''/* config.h. Generated by SCons. */
981 * This file is part of LyX, the document processor.
982 * Licence details can be found in the file COPYING.
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.
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'),
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>
1031 return std::count(a, a+5, 'l');
1034 ('getcwd', 'HAVE_GETCWD', None),
1035 ('setenv', 'HAVE_SETENV', None),
1036 ('putenv', 'HAVE_PUTENV', None),
1037 ('fcntl', 'HAVE_FCNTL', None),
1040 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1041 '#include <streambuf>\n#include <istream>')
1044 ('gdi32', 'HAVE_LIBGDI32'),
1045 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1048 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1050 'Define is sys/types.h does not have pid_t',
1052 '#define pid_t int',
1054 (conf.CheckCXXGlobalCstd(),
1056 'Define if your C++ compiler puts C library functions in the global namespace'
1058 (conf.CheckMkdirOneArg(),
1059 'MKDIR_TAKES_ONE_ARG',
1060 'Define if mkdir takes only one argument.'
1062 (conf.CheckIconvConst(),
1064 'Define as const if the declaration of iconv() needs const.',
1065 '#define ICONV_CONST const',
1066 '#define ICONV_CONST',
1068 (conf.CheckLC_MESSAGES(),
1070 'Define if your <locale.h> file defines LC_MESSAGES.'
1072 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1075 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1077 (env['nls'] and not included_gettext,
1079 'Define to 1 if using system gettext library'
1081 (env.has_key('warnings') and env['warnings'],
1083 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1085 (env.has_key('concept_checks') and env['concept_checks'],
1086 '_GLIBCXX_CONCEPT_CHECKS',
1087 'libstdc++ concept checking'
1089 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1091 'libstdc++ debug mode'
1093 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1094 '_GLIBCXX_DEBUG_PEDANTIC',
1095 'libstdc++ pedantic debug mode'
1097 (os.name != 'nt', 'BOOST_POSIX',
1098 'Indicates to boost which API to use (posix or windows).'
1100 (spell_engine is not None, spell_engine,
1101 'Spell engine to use'
1105 ('#define PACKAGE "%s%s"' % (package, program_suffix),
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'."),
1130 config_post = '''/************************************************************
1131 ** You should not need to change anything beyond this point */
1133 #ifndef HAVE_STRERROR
1134 #if defined(__cplusplus)
1137 char * strerror(int n);
1141 #ifndef HAVE_DECL_MKSTEMP
1142 #if defined(__cplusplus)
1149 #include <../boost/config.h>
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]
1164 # if nls=yes and gettext=included, create intl/config.h
1165 # intl/libintl.h etc
1167 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1168 if env['nls'] and included_gettext:
1170 print "Creating %s..." % intl_config_h
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. */
1180 * This file is part of LyX, the document processor.
1181 * Licence details can be found in the file COPYING.
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.
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'),
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),
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>'),
1241 (conf.CheckLC_MESSAGES(),
1243 'Define if your <locale.h> file defines LC_MESSAGES.'
1245 (conf.CheckIconvConst(),
1247 'Define as const if the declaration of iconv() needs const.',
1248 '#define ICONV_CONST const',
1249 '#define ICONV_CONST',
1251 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1252 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1254 "Define to 1 if you have the `intmax_t' type."
1256 (env.has_key('nls') and env['nls'],
1258 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1262 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found')
1264 config_post = '#endif'
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]
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]
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]
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')])
1302 # Finish auto-configuration
1305 #----------------------------------------------------------
1306 # Now set up our build process accordingly
1307 #----------------------------------------------------------
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']
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'
1331 qt_lib_suffix = '_debug'
1334 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
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++?
1341 system_libs = [env['ICONV_LIB'], 'ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
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']
1349 system_libs = [env['ICONV_LIB'], 'z']
1352 ('HAVE_LIBGDI32', 'gdi32'),
1353 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1354 ('USE_ASPELL', aspell_lib),
1355 ('USE_ISPELL', 'ispell'),
1356 ('USE_PSPELL', 'pspell'),
1361 system_libs.append(lib[1])
1364 # Build parameters CPPPATH etc
1367 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1370 # boost: for boost header files
1371 # BUILDDIR/common: for config.h
1372 # TOP_SRCDIR/src: for support/* etc
1374 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
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.
1381 env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1384 env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1386 env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
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')
1392 # QT_INC_PATH is not needed for *every* source file
1393 env['CPPPATH'].remove(qt_inc_path)
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
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'])
1410 # fill in the version info
1411 env['VERSION_INFO'] = '''Configuration
1413 Special build flags: %s
1415 C Compiler flags: %s %s
1417 C++ Compiler LyX flags: %s
1418 C++ Compiler flags: %s %s
1420 Linker user flags: %s
1422 Builing directory: %s
1423 Local library directory: %s
1426 Frontend libraries: %s
1427 System libraries: %s
1428 include search path: %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'])
1446 if frontend in ['qt3', 'qt4']:
1447 env['VERSION_INFO'] += ''' include dir: %s
1450 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1453 print env['VERSION_INFO']
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
1460 # I also would like to add logging (commands only) capacity to the
1462 logfile = env.get('logfile', default_log_file)
1463 if logfile != '' or platform_name == 'win32':
1465 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1466 info = '''# This is a log of commands used by scons to build lyx
1470 ''' % (time.asctime(), ' '.join(sys.argv),
1471 env['VERSION_INFO'].replace('\n','\n# ')) )
1476 # -h will print out help info
1477 Help(opts.GenerateHelpText(env))
1479 # save environment settings (for fast_start option)
1480 cache_file = open(env_cache_file, 'w')
1481 cPickle.dump(env_cache, cache_file)
1485 #----------------------------------------------------------
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))
1494 print "Building all targets recursively"
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
1505 rebuild_targets = None
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)
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)
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
1538 # now, if rebuild_targets is specified, do not rebuild some targets
1539 if rebuild_targets is not None:
1541 def ifBuildLib(name, libname, old_value):
1542 # explicitly asked to rebuild
1543 if name in rebuild_targets:
1545 # else if not rebuild, and if the library already exists
1546 elif libExists(libname):
1548 # do not change the original 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)
1563 def ifBuildApp(name, appname, old_value):
1564 # explicitly asked to rebuild
1565 if name in rebuild_targets:
1567 # else if not rebuild, and if the library already exists
1568 elif appExists(name, appname):
1570 # do not change the original value
1573 build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1574 build_client = ifBuildApp('client', 'lyxclient', build_client)
1576 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1588 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1590 boostenv = env.Copy()
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>"'])
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)]
1602 Alias('boost', boostlib)
1609 intlenv = env.Copy()
1611 print "Processing files in intl..."
1613 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1615 # we need the original C compiler for these files
1616 intlenv['CC'] = C_COMPILER
1617 intlenv['CCFLAGS'] = C_CCFLAGS
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
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\"',
1628 '-DENABLE_RELOCATABLE=1',
1630 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1632 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1633 '-Drelocate=libintl_relocate',
1634 '-DDEPENDS_ON_LIBICONV=1',
1639 intl = intlenv.StaticLibrary(
1640 target = '$LOCALLIBPATH/included_intl',
1642 source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1648 # Now, src code under src/
1650 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1657 print "Processing files in src/support..."
1659 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1661 support = env.StaticLibrary(
1662 target = '$LOCALLIBPATH/support',
1663 source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1665 Alias('support', support)
1672 print "Processing files in src/mathed..."
1674 mathed = env.StaticLibrary(
1675 target = '$LOCALLIBPATH/mathed',
1676 source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1678 Alias('mathed', mathed)
1685 print "Processing files in src/insets..."
1687 insets = env.StaticLibrary(
1688 target = '$LOCALLIBPATH/insets',
1689 source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1691 Alias('insets', insets)
1698 print "Processing files in src/frontends..."
1700 frontends = env.StaticLibrary(
1701 target = '$LOCALLIBPATH/frontends',
1702 source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1704 Alias('frontends', frontends)
1711 print "Processing files in src/graphics..."
1713 graphics = env.StaticLibrary(
1714 target = '$LOCALLIBPATH/graphics',
1715 source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1717 Alias('graphics', graphics)
1720 if build_controllers:
1722 # src/frontends/controllers
1724 print "Processing files in src/frontends/controllers..."
1726 controllers = env.StaticLibrary(
1727 target = '$LOCALLIBPATH/controllers',
1728 source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1730 Alias('controllers', controllers)
1734 # src/frontend/qt3/4
1736 if build_qt3 or build_qt4:
1737 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1740 print "Processing files in src/frontends/qt3..."
1743 # disable auto scan to speed up non build time
1744 qt3env['QT_AUTOSCAN'] = 0
1745 qt3env['QT_MOCHPREFIX'] = ''
1750 qt3env.AppendUnique(CPPPATH = [
1752 '$BUILDDIR/common/images',
1753 '$BUILDDIR/common/frontends',
1754 '$BUILDDIR/common/frontends/qt3',
1755 '$BUILDDIR/common/frontends/controllers',
1759 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
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]
1764 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1765 src_frontends_qt3_ui_files]
1767 qt3_uiced_cc_files = []
1768 for x in qt3_uiced_files:
1769 qt3_uiced_cc_files.extend(x[1:])
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
1780 print "Processing files in src/frontends/qt4..."
1783 qt4env['QT_AUTOSCAN'] = 0
1785 # local qt4 toolset from
1786 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1788 # NOTE: I have to patch qt4.py since it does not automatically
1789 # process .C file!!! (add to cxx_suffixes )
1791 qt4env.Tool('qt4', [scons_dir])
1792 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1794 qt4env.AppendUnique(CPPPATH = [
1796 '$BUILDDIR/common/images',
1797 '$BUILDDIR/common/frontends',
1798 '$BUILDDIR/common/frontends/qt4',
1799 '$BUILDDIR/common/frontends/controllers',
1804 # FIXME: replace by something from pkg_config
1805 qt4env.Append(CCFLAGS = [
1807 '-DQT_CLEAN_NAMESPACE',
1815 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
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]]
1824 # moc qt4_moc_files, the moced files are included in the original files
1826 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1828 qt4 = qt4env.StaticLibrary(
1829 target = '$LOCALLIBPATH/qt4',
1830 source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1839 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1841 print "Processing files in src/client..."
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]
1850 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1851 client, [Copy('$TARGET', '$SOURCE')]))
1854 Alias('client', client)
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')]
1867 print "Processing files in src/tex2lyx..."
1869 tex2lyx_env = env.Copy()
1871 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1872 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
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')])
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]
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)
1888 # define tex2lyx even if tex2lyx is not built with rebuild=no
1889 tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1896 print "Processing files in src..."
1898 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
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')
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]
1913 lyxbase_post = env.StaticLibrary(
1914 target = '$LOCALLIBPATH/lyxbase_post',
1915 source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1917 Alias('lyxbase', lyxbase_pre)
1918 Alias('lyxbase', lyxbase_post)
1923 # Build lyx with given frontend
1926 target = '$BUILDDIR/$frontend/lyx',
1927 source = ['$BUILDDIR/common/main.C'],
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')]))
1951 # define lyx even if lyx is not built with rebuild=no
1952 lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
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
1964 rebuildTargetOnly: whether or not only rebuild this target
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.
1970 if rebuildTargetOnly:
1971 cmds = 'fast_start=yes rebuild='+target
1973 cmds = 'fast_start=yes'
1974 if full_target is None:
1975 build_target = target
1977 build_target = full_target
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,
1990 Alias('msvs_projects', proj)
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)
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])
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])
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])
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])
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])
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])
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])
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])
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])
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)
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)
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])
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)
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)
2087 print 'Processing files in po...'
2092 # files to translate
2093 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2094 # possibly *only* handle these languages
2096 if env.has_key('languages'):
2097 languages = env.make_list(env['lanauges'])
2098 # use defulat msgfmt
2100 if not env['MSGFMT']:
2101 print 'msgfmt does not exist. Can not process po files'
2104 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2106 for f in transfiles:
2108 fname = os.path.split(f)[1]
2110 country = fname.split('.')[0]
2112 if not languages or country in languages:
2113 gmo_files.extend(env.Transfiles(f))
2116 if 'install' in targets:
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
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 '''
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:])
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):
2139 os.makedirs(dest_prefix_dir)
2142 if not os.path.isdir(dest_prefix_dir):
2143 print 'Can not create directory', dest_prefix_dir
2146 if env.has_key('exec_prefix'):
2147 bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2149 bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2151 share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
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)
2159 # install executables (lyxclient may be None)
2162 version_suffix = program_suffix
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)
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)
2183 # install lyxclient, may not exist
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)
2192 for (dir,files) in [
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]))
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)
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']])
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)
2236 Alias('all', ['lyx', 'client', 'tex2lyx'])