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
21 #----------------------------------------------------------
22 # Required runtime environment
23 #----------------------------------------------------------
25 # scons asks for 1.5.2, lyx requires 2.3
26 EnsurePythonVersion(2, 3)
27 # Please use at least 0.96.91 (not 0.96.1)
28 EnsureSConsVersion(0, 96)
30 # determine where I am ...
32 # called as 'cd development/scons; scons'
33 if os.path.isfile('SConstruct'):
36 # called as 'scons -f development/scons/SConstruct'
39 scons_dir = 'development/scons'
42 #----------------------------------------------------------
44 #----------------------------------------------------------
46 # some global settings
48 # detect version of lyx
49 # only 1.4.x has frontends/qt2
50 if os.path.isdir(os.path.join(top_src_dir, 'src', 'frontends', 'qt2')):
51 package_version = '1.4.2svn'
52 boost_version = '1_32'
54 package_version = '1.5.0svn'
55 boost_version = '1_33_1'
58 default_build_mode = 'debug'
62 package_bugreport = 'lyx-devel@lists.lyx.org'
64 package_tarname = 'lyx'
65 package_string = '%s %s' % (package_name, package_version)
67 # various cache/log files
68 default_log_file = 'scons_lyx.log'
69 env_cache_file = 'env.cache'
72 #----------------------------------------------------------
73 # platform dependent settings
74 #----------------------------------------------------------
77 platform_name = 'win32'
78 default_frontend = 'qt4'
79 default_prefix = 'c:/program files/lyx'
80 default_with_x = False
81 default_packaging_method = 'windows'
82 elif os.name == 'posix' and sys.platform != 'cygwin':
83 platform_name = sys.platform
84 default_frontend = 'qt3'
85 default_prefix = '/usr/local'
87 default_packaging_method = 'posix'
88 elif os.name == 'posix' and sys.platform == 'cygwin':
89 platform_name = 'cygwin'
90 default_frontend = 'qt3'
91 default_prefix = '/usr/local'
93 default_packaging_method = 'posix'
94 elif os.name == 'darwin':
95 platform_name = 'macosx'
96 default_frontend = 'qt3'
97 # FIXME: macOSX default prefix?
99 default_with_x = False
100 default_packaging_method = 'macosx'
101 else: # unsupported system, assume posix behavior
102 platform_name = 'others'
103 default_frontend = 'qt3'
105 default_with_x = True
106 default_packaging_method = 'posix'
108 # 1.4.2 only has qt2 frontend
109 if package_version == '1.4.2svn':
110 default_frontend = 'qt2'
112 #---------------------------------------------------------
114 #----------------------------------------------------------
116 # You can set perminant default values in config.py
117 if os.path.isfile('config.py'):
118 print "Getting options from config.py..."
119 print open('config.py').read()
121 opts = Options(['config.py'])
124 EnumOption('frontend', 'Main GUI', default_frontend,
125 allowed_values = ('xform', 'qt2', 'qt3', 'qt4', 'gtk') ),
126 # debug or release build
127 EnumOption('mode', 'Building method', default_build_mode,
128 allowed_values = ('debug', 'release') ),
131 'Use included, system boost library, or try sytem boost first.',
132 'auto', allowed_values = (
133 'auto', # detect boost, if not found, use included
134 'included', # always use included boost
135 'system', # always use system boost, fail if can not find
138 EnumOption('gettext',
139 'Use included, system gettext library, or try sytem gettext first',
140 'auto', allowed_values = (
141 'auto', # detect gettext, if not found, use included
142 'included', # always use included gettext
143 'system', # always use system gettext, fail if can not find
146 EnumOption('spell', 'Choose spell checker to use.', 'auto',
147 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
149 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
150 allowed_values = ('windows', 'posix', 'macosx')),
152 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
153 # No precompiled header support (too troublesome to make it work for msvc)
154 # BoolOption('pch', 'Whether or not use pch', False),
155 # enable assertion, (config.h has ENABLE_ASSERTIOS
156 BoolOption('assertions', 'Use assertions', True),
157 # enable warning, (config.h has WITH_WARNINGS)
158 # default to False since MSVC does not have #warning
159 BoolOption('warnings', 'Use warnings', False),
160 # config.h define _GLIBCXX_CONCEPT_CHECKS
161 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
162 BoolOption('concept_checks', 'Enable concept checks', True),
164 BoolOption('nls', 'Whether or not use native language support', True),
166 BoolOption('profiling', 'Whether or not enable profiling', False),
167 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
168 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
170 BoolOption('X11', 'Use x11 windows system', default_with_x),
171 # use MS VC++ to build lyx
172 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
174 PathOption('qt_dir', 'Path to qt directory', None),
176 PathOption('qt_inc_path', 'Path to qt include directory', None),
178 PathOption('qt_lib_path', 'Path to qt library directory', None),
179 # extra include and libpath
180 PathOption('extra_inc_path', 'Extra include path', None),
182 PathOption('extra_lib_path', 'Extra library path', None),
184 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
186 PathOption('extra_inc_path1', 'Extra include path', None),
188 PathOption('extra_lib_path1', 'Extra library path', None),
189 # rebuild only specifed, comma separated targets
190 ('rebuild', 'rebuild only specifed, comma separated 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),
223 # copied from SCons/Options/BoolOption.py
224 # We need to use them before a boolean ARGUMENTS option is available
226 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
227 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
229 # whether or not use current config.h, and cached tests
231 # if fast_start=yes (default), load variables from env_cache_file
232 if (not ARGUMENTS.has_key('fast_start') or \
233 ARGUMENTS['fast_start'] in true_strings) \
234 and os.path.isfile(env_cache_file):
236 cache_file = open(env_cache_file)
237 env_cache = cPickle.load(cache_file)
239 print '------------ fast_start mode --------------------'
240 print ' Use cached test results and current config.h'
241 print ' use fast_start=no to override'
247 # if load_option=yes (default), load saved comand line options
249 # This option can take value yes/no/opt1,opt2/-opt1,opt2
250 # and tries to be clever in choosing options to load
251 if (not ARGUMENTS.has_key('load_option') or \
252 ARGUMENTS['load_option'] not in false_strings) \
253 and os.path.isfile(env_cache_file):
254 cache_file = open(env_cache_file)
255 opt_cache = cPickle.load(cache_file)['arg_cache']
257 # import cached options, but we should ignore qt_dir when frontend changes
258 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
259 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
260 and opt_cache.has_key('qt_dir'):
261 opt_cache.pop('qt_dir')
262 # some options will require full rebuild
263 # these are in general things that will change config.h
264 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
265 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
266 ARGUMENTS[arg] != opt_cache[arg]):
268 print " ** fast_start is disabled because of the change of option", arg
271 # and we do not cache some options
272 for arg in ['fast_start', 'load_option']:
273 if opt_cache.has_key(arg):
275 # now, if load_option=opt1,opt2 or -opt1,opt2
276 if ARGUMENTS.has_key('load_option') and \
277 ARGUMENTS['load_option'] not in true_strings + false_strings:
278 # if -opt1,opt2 is specified, do not load these options
279 if ARGUMENTS['load_option'][0] == '-':
280 for arg in ARGUMENTS['load_option'][1:].split(','):
281 if opt_cache.has_key(arg):
283 # if opt1,opt2 is specified, only load specified options
285 args = ARGUMENTS['load_option'].split(',')
286 for arg in opt_cache.keys():
289 # now restore options as if entered from command line
290 for key in opt_cache.keys():
291 if not ARGUMENTS.has_key(key):
292 ARGUMENTS[key] = opt_cache[key]
293 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
297 env_cache['arg_cache'] = ARGUMENTS
300 #---------------------------------------------------------
301 # Setting up environment
302 #---------------------------------------------------------
304 # I do not really like ENV=os.environ, but you may add it
305 # here if you experience some environment related problem
306 env = Environment(options = opts)
308 # set individual variables since I do not really like ENV = os.environ
309 env['ENV']['PATH'] = os.environ.get('PATH')
310 env['ENV']['HOME'] = os.environ.get('HOME')
311 # these are defined for MSVC
312 env['ENV']['LIB'] = os.environ.get('LIB')
313 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
315 # for simplicity, use var instead of env[var]
316 frontend = env['frontend']
317 prefix = env['prefix']
320 if platform_name == 'win32':
321 if env.has_key('use_vc'):
322 use_vc = env['use_vc']
323 if WhereIs('cl.exe') is None:
324 print "cl.exe is not found. Are you using the MSVC environment?"
326 elif WhereIs('cl.exe') is not None:
333 # lyx will be built to $build/build_dir so it is possible
334 # to build multiple build_dirs using the same source
335 # $mode can be debug or release
336 if env.has_key('build_dir') and env['build_dir'] is not None:
337 # create the directory if needed
338 if not os.path.isdir(env['build_dir']):
340 os.makedirs(env['build_dir'])
343 if not os.path.isdir(env['build_dir']):
344 print 'Can not create directory', env['build_dir']
346 env['BUILDDIR'] = env['build_dir']
348 # Determine the name of the build $mode
349 env['BUILDDIR'] = '#' + mode
351 # all built libraries will go to build_dir/libs
352 # (This is different from the make file approach)
353 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
354 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
357 # Here is a summary of variables defined in env
359 # 2. undefined options with a non-None default value
360 # 3. compiler commands and flags like CCFLAGS.
361 # MSGFMT used to process po files
362 # 4. Variables that will be used to replace variables in some_file.in
363 # src/support/package.C.in:
364 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
365 # lib/lyx2lyx/lyx2lyx_version.py.in
368 # PACKAGE_VERSION, VERSION_INFO
369 # src/frontends/xforms/lyx_xpm.h.in
371 # src/frontends/xforms/lyx_forms.h.in
374 # full path name is used to build msvs project files
375 # and to replace TOP_SRCDIR in package.C
376 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
377 # needed by src/version.C.in => src/version.C
378 env['PACKAGE_VERSION'] = package_version
380 # determine share_dir etc
381 packaging_method = env.get('packaging')
382 if packaging_method == 'windows':
383 share_dir = 'Resources'
384 man_dir = 'Resources/man/man1'
385 locale_dir = 'Resources/locale'
386 default_prefix = 'c:/program files/lyx'
388 share_dir = 'share/lyx'
390 locale_dir = 'share/locale'
391 default_prefix = '/usr/local/'
393 # install to default_prefix by default
394 # program suffix: can be yes, or a string
395 if env.has_key('version_suffix'):
396 if env['version_suffix'] in true_strings:
397 program_suffix = package_version
398 elif env['version_suffix'] in false_strings:
401 program_suffix = env['version_suffix']
404 # used by package.C.in
405 env['PROGRAM_SUFFIX'] = program_suffix
407 # whether or not add suffix to file and directory names
408 add_suffix = packaging_method != 'windows'
409 # LYX_DIR are different (used in package.C.in)
411 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
413 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
414 # we need absolute path for package.C
415 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
418 #---------------------------------------------------------
419 # Setting building environment (Tools, compiler flags etc)
420 #---------------------------------------------------------
422 # Since Tool('mingw') will reset CCFLAGS etc, this should be
423 # done before getEnvVariable
424 if platform_name == 'win32':
430 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
432 # we differentiate between hard-coded options and default options
433 # hard-coded options are required and will always be there
434 # default options can be replaced by enviromental variables or command line options
435 CCFLAGS_required = []
436 LINKFLAGS_required = []
439 # under windows, scons is confused by .C/.c and uses gcc instead of
440 # g++. I am forcing the use of g++ here. This is expected to change
441 # after lyx renames all .C files to .cpp
443 # save the old c compiler and CCFLAGS (used by libintl)
444 C_COMPILER = env.subst('$CC')
445 C_CCFLAGS = env.subst('$CCFLAGS').split()
446 # if we use ms vc, the commands are fine (cl.exe and link.exe)
448 # /TP treat all source code as C++
449 # C4819: The file contains a character that cannot be represented
450 # in the current code page (number)
451 # C4996: foo was decleared deprecated
452 CCFLAGS_required.extend(['/TP', '/EHsc'])
453 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
455 if env.has_key('CXX') and env['CXX']:
456 env['CC'] = env.subst('$CXX')
457 env['LINK'] = env.subst('$CXX')
462 # for debug/release mode
463 if env.has_key('optimization') and env['optimization'] is not None:
464 # if user supplies optimization flags, use it anyway
465 CCFLAGS_required.extend(env['optimization'].split())
466 # and do not use default
467 set_default_optimization_flags = False
469 set_default_optimization_flags = True
473 CCFLAGS_required.append('/Zi')
474 LINKFLAGS_required.extend(['/debug', '/map'])
476 CCFLAGS_required.append('-g')
477 CCFLAGS_default.append('-O')
478 elif mode == 'release' and set_default_optimization_flags:
480 CCFLAGS_default.append('/O2')
482 CCFLAGS_default.append('-O2')
484 # msvc uses separate tools for profiling
485 if env.has_key('profiling') and env['profiling']:
487 print 'Visual C++ does not use profiling options'
489 CCFLAGS_required.append('-pg')
490 LINKFLAGS_required.append('-pg')
492 if env.has_key('warnings') and env['warnings']:
494 CCFLAGS_default.append('/W2')
496 # Note: autotools detect gxx version and pass -W for 3.x
497 # and -Wextra for other versions of gcc
498 CCFLAGS_default.append('-Wall')
500 # Now, set the variables as follows:
501 # 1. if command line option exists: replace default
502 # 2. then if s envronment variable exists: replace default
503 # 3. set variable to required + default
504 def setEnvVariable(env, name, required = None, default = None, split = True):
505 ''' env: environment to set variable
507 required: hardcoded options
508 default: default options that can be replaced by command line or
509 environment variables
510 split: whether or not split obtained variable like '-02 -g'
512 # first try command line argument (override environment settings)
513 if ARGUMENTS.has_key(name):
514 default = ARGUMENTS[name]
516 default = default.split()
517 # then use environment default
518 elif os.environ.has_key(name):
519 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
520 default = os.environ[name]
522 default = default.split()
524 if required is not None:
526 if default is not None:
527 if env.has_key(name) and env[name] != default:
532 setEnvVariable(env, 'DESTDIR', split=False)
533 setEnvVariable(env, 'CC')
534 setEnvVariable(env, 'LINK')
535 setEnvVariable(env, 'CPP')
536 setEnvVariable(env, 'CXX')
537 setEnvVariable(env, 'CXXCPP')
538 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
539 setEnvVariable(env, 'CXXFLAGS')
540 setEnvVariable(env, 'CPPFLAGS')
541 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
543 # if DESTDIR is not set...
544 if env.has_key('dest_dir'):
545 print "This option is obsolete. Please use DESTDIR instead."
546 env['DESTDIR'] = env['dest_dir']
549 #---------------------------------------------------------
550 # Frontend related variables (QTDIR etc)
551 #---------------------------------------------------------
553 if env.has_key('qt_dir') and env['qt_dir']:
554 env['QTDIR'] = env['qt_dir']
555 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
556 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
558 # if there is a valid QTDIR, set path for lib and bin directories
559 if env.has_key('QTDIR'):
560 # add path to the qt tools
561 if os.path.isdir(os.path.join(env['QTDIR'], 'lib')):
562 env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')])
563 # set environment so that moc etc can be found even if its path is not set properly
564 if os.path.isdir(os.path.join(env['QTDIR'], 'bin')):
565 os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin')
566 env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin'))
568 # allow qt2 frontend to locate qt3 libs.
569 frontend_lib = {'qt2':'qt3', 'qt3':'qt3', 'qt4':'qt4'}[frontend]
570 if env.has_key('qt_lib_path') and env['qt_lib_path']:
571 qt_lib_path = env.subst('$qt_lib_path')
572 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
573 qt_lib_path = env.subst('$QTDIR/lib')
574 # this is the path for cygwin.
575 elif os.path.isdir(os.path.join('/usr/lib/', frontend_lib, 'lib')):
576 qt_lib_path = '/usr/lib/%s/lib' % frontend_lib
578 print "Qt library directory is not found. Please specify it using qt_lib_path"
580 env.AppendUnique(LIBPATH = [qt_lib_path])
581 # qt4 seems to be using pkg_config
582 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
584 if env.has_key('qt_inc_path') and env['qt_inc_path']:
585 qt_inc_path = env['qt_inc_path']
586 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
587 qt_inc_path = '$QTDIR/include'
588 # this is the path for cygwin.
589 elif os.path.isdir('/usr/include/' + frontend_lib):
590 qt_inc_path = '/usr/include/' + frontend_lib
592 print "Qt include directory not found. Please specify it using qt_inc_path"
594 # Note that this CPPPATH is for testing only
595 # it will be removed before calling SConscript
596 env['CPPPATH'] = [qt_inc_path]
599 # extra_inc_path and extra_lib_path
602 if env.has_key('extra_inc_path') and env['extra_inc_path']:
603 extra_inc_paths.append(env['extra_inc_path'])
604 if env.has_key('extra_lib_path') and env['extra_lib_path']:
605 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
606 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
607 extra_inc_paths.append(env['extra_inc_path1'])
608 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
609 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
610 if env.has_key('extra_bin_path') and env['extra_bin_path']:
611 # only the first one is needed (a scons bug?)
612 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
613 env.PrependENVPath('PATH', env['extra_bin_path'])
614 # extra_inc_paths will be used later by intlenv etc
615 env.AppendUnique(CPPPATH = extra_inc_paths)
618 #----------------------------------------------------------
620 #----------------------------------------------------------
622 conf = Configure(env,
624 'CheckPkgConfig' : utils.checkPkgConfig,
625 'CheckPackage' : utils.checkPackage,
626 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
627 'CheckSelectArgType' : utils.checkSelectArgType,
628 'CheckBoostLibraries' : utils.checkBoostLibraries,
629 'CheckCommand' : utils.checkCommand,
630 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
631 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
632 'CheckIconvConst' : utils.checkIconvConst,
636 # pkg-config? (if not, we use hard-coded options)
638 if conf.CheckPkgConfig('0.15.0'):
639 env['HAS_PKG_CONFIG'] = True
641 print 'pkg-config >= 0.1.50 is not found'
642 env['HAS_PKG_CONFIG'] = False
643 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
645 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
647 # zlib? This is required. (fast_start assumes the existance of zlib)
649 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
650 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
651 print 'Did not find zdll.lib or zlib.h, exiting!'
657 # qt3 does not use pkg_config
658 if frontend in ['qt2', 'qt3']:
659 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
660 print 'Did not find qt libraries, exiting!'
662 elif frontend == 'qt4':
664 # first: try pkg_config
665 if env['HAS_PKG_CONFIG']:
666 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
667 # FIXME: use pkg_config information?
668 #env['QT4_PKG_CONFIG'] = succ
669 # second: try to link to it
671 # Under linux, I can test the following perfectly
672 # Under windows, lib names need to passed as libXXX4.a ...
673 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
674 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
675 # third: try to look up the path
678 for lib in ['QtCore', 'QtGui']:
679 # windows version has something like QtGui4 ...
680 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
681 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
684 # still can not find it
686 print "Qt4 libraries are found."
688 print 'Did not find qt libraries, exiting!'
691 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
694 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
696 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
697 if os.path.isfile(manifest):
698 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
703 if conf.CheckLib('socket'):
704 socket_libs.append('socket')
705 # nsl is the network services library and provides a
706 # transport-level interface to networking services.
707 if conf.CheckLib('nsl'):
708 socket_libs.append('nsl')
709 env_cache['SOCKET_LIBS'] = socket_libs
711 socket_libs = env_cache['SOCKET_LIBS']
713 # check available boost libs (since lyx1.4 does not use iostream)
715 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
716 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
717 boost_libs.append(lib)
720 # check boost libraries
721 boost_opt = ARGUMENTS.get('boost', 'auto')
722 # check for system boost
723 lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
724 inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
725 # default to $BUILDDIR/libs (use None since this path will be added anyway)
727 # here I assume that all libraries are in the same directory
728 if boost_opt == 'included':
729 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
730 included_boost = True
731 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
732 elif boost_opt == 'auto':
733 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
734 # if not found, use local boost
736 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
737 included_boost = True
738 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
740 included_boost = False
741 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
742 elif boost_opt == 'system':
743 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
745 print "Can not find system boost libraries with version %s " % boost_version
746 print "Please supply a path through extra_lib_path and try again."
747 print "Or use boost=included to use included boost libraries."
750 included_boost = False
751 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
752 env_cache['BOOST_LIBRARIES'] = boost_libraries
753 env_cache['INCLUDED_BOOST'] = included_boost
754 env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
755 env_cache['BOOST_LIBPATH'] = boost_libpath
757 boost_libraries = env_cache['BOOST_LIBRARIES']
758 included_boost = env_cache['INCLUDED_BOOST']
759 env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
760 boost_libpath = env_cache['BOOST_LIBPATH']
762 if boost_libpath is not None:
763 env.AppendUnique(LIBPATH = [boost_libpath])
766 env['ENABLE_NLS'] = env['nls']
769 if not env['ENABLE_NLS']:
771 included_gettext = False
773 # check gettext libraries
774 gettext_opt = ARGUMENTS.get('gettext', 'auto')
775 # check for system gettext
777 if gettext_opt in ['auto', 'system']:
778 if conf.CheckLib('intl'):
779 included_gettext = False
783 if gettext_opt == 'system':
784 print "Can not find system gettext library"
785 print "Please supply a path through extra_lib_path and try again."
786 print "Or use gettext=included to use included gettext libraries."
788 # now, auto and succ = false, or gettext=included
790 # we do not need to set LIBPATH now.
791 included_gettext = True
792 intl_libs = ['included_intl']
793 env_cache['INCLUDED_GETTEXT'] = included_gettext
794 env_cache['INTL_LIBS'] = intl_libs
796 included_gettext = env_cache['INCLUDED_GETTEXT']
797 intl_libs = env_cache['INTL_LIBS']
800 # check for msgfmt command
802 env['MSGFMT'] = conf.CheckCommand('msgfmt')
803 env_cache['MSGFMT'] = env['MSGFMT']
805 env['MSGFMT'] = env_cache['MSGFMT']
807 # check uic and moc commands for qt frontends
809 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
810 or conf.CheckCommand('moc') == None):
811 print 'uic or moc command is not found for frontend', frontend
815 # Customized builders
817 # install customized builders
818 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
821 #----------------------------------------------------------
822 # Generating config.h
823 #----------------------------------------------------------
824 aspell_lib = 'aspell'
825 # assume that we use aspell, aspelld compiled for msvc
826 if platform_name == 'win32' and mode == 'debug' and use_vc:
827 aspell_lib = 'aspelld'
829 # check the existence of config.h
830 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
831 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
832 if not fast_start or not os.path.isfile(boost_config_h) \
833 or not os.path.isfile(config_h):
835 print "Creating %s..." % boost_config_h
837 utils.createConfigFile(conf,
838 config_file = boost_config_h,
839 config_pre = '''/* boost/config.h. Generated by SCons. */
844 * This file is part of LyX, the document processor.
845 * Licence details can be found in the file COPYING.
847 * This is the compilation configuration file for LyX.
848 * It was generated by scon.
849 * You might want to change some of the defaults if something goes wrong
850 * during the compilation.
853 #ifndef _BOOST_CONFIG_H
854 #define _BOOST_CONFIG_H
857 ('ostream', 'HAVE_OSTREAM', 'cxx'),
858 ('locale', 'HAVE_LOCALE', 'cxx'),
859 ('sstream', 'HAVE_SSTREAM', 'cxx'),
860 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
863 (env.has_key('assertions') and env['assertions'],
865 'Define if you want assertions to be enabled in the code'
870 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
871 # define USE_BOOST_FORMAT 1
873 # define USE_BOOST_FORMAT 0
876 #if !defined(ENABLE_ASSERTIONS)
877 # define BOOST_DISABLE_ASSERTS 1
879 #define BOOST_ENABLE_ASSERT_HANDLER 1
881 #define BOOST_DISABLE_THREADS 1
882 #define BOOST_NO_WREGEX 1
883 #define BOOST_NO_WSTRING 1
886 # define BOOST_POSIX 1
889 #define BOOST_ALL_NO_LIB 1
891 #if defined(HAVE_NEWAPIS_H)
892 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
899 print "\nGenerating %s..." % config_h
901 # AIKSAURUS_H_LOCATION
902 if (conf.CheckCXXHeader("Aiksaurus.h")):
903 aik_location = '<Aiksaurus.h>'
904 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
905 aik_location = '<Aiksaurus/Aiksaurus.h>'
909 # determine headers to use
910 spell_opt = ARGUMENTS.get('spell', 'auto')
911 env['USE_ASPELL'] = False
912 env['USE_PSPELL'] = False
913 env['USE_ISPELL'] = False
914 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
915 spell_engine = 'USE_ASPELL'
916 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
917 spell_engine = 'USE_PSPELL'
918 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
919 spell_engine = 'USE_ISPELL'
923 if spell_engine is not None:
924 env[spell_engine] = True
926 if spell_opt == 'auto':
927 print "Warning: Can not locate any spell checker"
928 elif spell_opt != 'no':
929 print "Warning: Can not locate specified spell checker:", spell_opt
932 # check arg types of select function
933 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
937 result = utils.createConfigFile(conf,
938 config_file = config_h,
939 config_pre = '''/* config.h. Generated by SCons. */
944 * This file is part of LyX, the document processor.
945 * Licence details can be found in the file COPYING.
947 * This is the compilation configuration file for LyX.
948 * It was generated by scon.
949 * You might want to change some of the defaults if something goes wrong
950 * during the compilation.
957 ('io.h', 'HAVE_IO_H', 'c'),
958 ('limits.h', 'HAVE_LIMITS_H', 'c'),
959 ('locale.h', 'HAVE_LOCALE_H', 'c'),
960 ('process.h', 'HAVE_PROCESS_H', 'c'),
961 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
962 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
963 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
964 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
965 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
966 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
967 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
968 ('utime.h', 'HAVE_UTIME_H', 'c'),
969 ('direct.h', 'HAVE_DIRECT_H', 'c'),
970 ('istream', 'HAVE_ISTREAM', 'cxx'),
971 ('ios', 'HAVE_IOS', 'cxx'),
974 ('open', 'HAVE_OPEN', None),
975 ('close', 'HAVE_CLOSE', None),
976 ('popen', 'HAVE_POPEN', None),
977 ('pclose', 'HAVE_PCLOSE', None),
978 ('_open', 'HAVE__OPEN', None),
979 ('_close', 'HAVE__CLOSE', None),
980 ('_popen', 'HAVE__POPEN', None),
981 ('_pclose', 'HAVE__PCLOSE', None),
982 ('getpid', 'HAVE_GETPID', None),
983 ('_getpid', 'HAVE__GETPID', None),
984 ('mkdir', 'HAVE_MKDIR', None),
985 ('_mkdir', 'HAVE__MKDIR', None),
986 ('mktemp', 'HAVE_MKTEMP', None),
987 ('mkstemp', 'HAVE_MKSTEMP', None),
988 ('strerror', 'HAVE_STRERROR', None),
989 ('count', 'HAVE_STD_COUNT', '''
994 return std::count(a, a+5, 'l');
997 ('getcwd', 'HAVE_GETCWD', None),
998 ('setenv', 'HAVE_SETENV', None),
999 ('putenv', 'HAVE_PUTENV', None),
1000 ('fcntl', 'HAVE_FCNTL', None),
1003 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1004 '#include <streambuf>\n#include <istream>')
1007 ('gdi32', 'HAVE_LIBGDI32'),
1008 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1009 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1012 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1014 'Define is sys/types.h does not have pid_t',
1016 '#define pid_t int',
1018 (conf.CheckCXXGlobalCstd(),
1020 'Define if your C++ compiler puts C library functions in the global namespace'
1022 (conf.CheckMkdirOneArg(),
1023 'MKDIR_TAKES_ONE_ARG',
1024 'Define if mkdir takes only one argument.'
1026 (conf.CheckLC_MESSAGES(),
1028 'Define if your <locale.h> file defines LC_MESSAGES.'
1030 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1033 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1035 (env['nls'] and not included_gettext,
1037 'Define to 1 if using system gettext library'
1039 (env.has_key('warnings') and env['warnings'],
1041 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1043 (env.has_key('concept_checks') and env['concept_checks'],
1044 '_GLIBCXX_CONCEPT_CHECKS',
1045 'libstdc++ concept checking'
1047 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1049 'libstdc++ debug mode'
1051 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1052 '_GLIBCXX_DEBUG_PEDANTIC',
1053 'libstdc++ pedantic debug mode'
1055 (os.name != 'nt', 'BOOST_POSIX',
1056 'Indicates to boost which API to use (posix or windows).'
1058 (spell_engine is not None, spell_engine,
1059 'Spell engine to use'
1063 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1065 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1066 'Define to the address where bug reports for this package should be sent.'),
1067 ('#define PACKAGE_NAME "%s"' % package_name,
1068 'Define to the full name of this package.'),
1069 ('#define PACKAGE_STRING "%s"' % package_string,
1070 'Define to the full name and version of this package.'),
1071 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1072 'Define to the one symbol short name of this package.'),
1073 ('#define PACKAGE_VERSION "%s"' % package_version,
1074 'Define to the version of this package.'),
1075 ('#define BOOST_ALL_NO_LIB 1',
1076 'disable automatic linking of boost libraries.'),
1077 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1078 'Packaging method'),
1079 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1080 'Aiksaurus include file'),
1081 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1082 "Define to the type of arg 1 for `select'."),
1083 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1084 "Define to the type of arg 2, 3, 4 for `select'."),
1085 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1086 "Define to the type of arg 5 for `select'."),
1088 config_post = '''/************************************************************
1089 ** You should not need to change anything beyond this point */
1091 #ifndef HAVE_STRERROR
1092 #if defined(__cplusplus)
1095 char * strerror(int n);
1099 #ifndef HAVE_DECL_MKSTEMP
1100 #if defined(__cplusplus)
1107 #include <../boost/config.h>
1113 # these keys are needed in env
1114 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1115 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1116 'ICONV_LIB', 'AIKSAURUS_LIB']:
1117 # USE_ASPELL etc does not go through result
1118 if result.has_key(key):
1119 env[key] = result[key]
1120 env_cache[key] = env[key]
1123 # if nls=yes and gettext=included, create intl/config.h
1124 # intl/libintl.h etc
1126 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1127 if env['nls'] and included_gettext:
1129 print "Creating %s..." % intl_config_h
1131 # create intl/config.h
1132 result = utils.createConfigFile(conf,
1133 config_file = intl_config_h,
1134 config_pre = '''/* intl/config.h. Generated by SCons. */
1139 * This file is part of LyX, the document processor.
1140 * Licence details can be found in the file COPYING.
1142 * This is the compilation configuration file for LyX.
1143 * It was generated by scon.
1144 * You might want to change some of the defaults if something goes wrong
1145 * during the compilation.
1152 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1153 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1154 ('string.h', 'HAVE_STRING_H', 'c'),
1155 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1156 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1157 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1158 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1159 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1160 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1161 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1164 ('getcwd', 'HAVE_GETCWD', None),
1165 ('stpcpy', 'HAVE_STPCPY', None),
1166 ('strcasecmp', 'HAVE_STRCASECMP', None),
1167 ('strdup', 'HAVE_STRDUP', None),
1168 ('strtoul', 'HAVE_STRTOUL', None),
1169 ('alloca', 'HAVE_ALLOCA', None),
1170 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1171 ('mempcpy', 'HAVE_MEMPCPY', None),
1172 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1173 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1174 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1175 ('setlocale', 'HAVE_SETLOCALE', None),
1176 ('tsearch', 'HAVE_TSEARCH', None),
1177 ('getegid', 'HAVE_GETEGID', None),
1178 ('getgid', 'HAVE_GETGID', None),
1179 ('getuid', 'HAVE_GETUID', None),
1180 ('wcslen', 'HAVE_WCSLEN', None),
1181 ('asprintf', 'HAVE_ASPRINTF', None),
1182 ('wprintf', 'HAVE_WPRINTF', None),
1183 ('snprintf', 'HAVE_SNPRINTF', None),
1184 ('printf', 'HAVE_POSIX_PRINTF', None),
1185 ('fcntl', 'HAVE_FCNTL', None),
1188 ('intmax_t', 'HAVE_INTMAX_T', None),
1189 ('long double', 'HAVE_LONG_DOUBLE', None),
1190 ('long long', 'HAVE_LONG_LONG', None),
1191 ('wchar_t', 'HAVE_WCHAR_T', None),
1192 ('wint_t', 'HAVE_WINT_T', None),
1193 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1194 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1197 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1201 (conf.CheckLC_MESSAGES(),
1203 'Define if your <locale.h> file defines LC_MESSAGES.'
1205 (conf.CheckIconvConst(),
1207 'Define as const if the declaration of iconv() needs const.',
1208 '#define ICONV_CONST',
1209 '#define ICONV_CONST const',
1211 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1212 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1214 "Define to 1 if you have the `intmax_t' type."
1216 (env.has_key('nls') and env['nls'],
1218 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1221 config_post = '#endif'
1224 # these keys are needed in env
1225 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1226 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1227 # USE_ASPELL etc does not go through result
1228 if result.has_key(key):
1229 env[key] = result[key]
1230 env_cache[key] = env[key]
1234 # this comes as a big surprise, without this line
1235 # (doing nothing obvious), adding fast_start=yes
1236 # to a build with fast_start=no will result in a rebuild
1237 # Note that the exact header file to check does not matter
1238 conf.CheckCHeader('io.h')
1239 # only a few variables need to be rescanned
1240 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1241 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1242 'ICONV_LIB', 'AIKSAURUS_LIB']:
1243 env[key] = env_cache[key]
1246 if env['nls'] and included_gettext:
1247 # only a few variables need to be rescanned
1248 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1249 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1250 env[key] = env_cache[key]
1252 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1253 if env['nls'] and included_gettext:
1254 # libgnuintl.h.in => libintl.h
1255 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1256 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1257 [Copy('$TARGET', '$SOURCE')])
1260 # Finish auto-configuration
1263 #----------------------------------------------------------
1264 # Now set up our build process accordingly
1265 #----------------------------------------------------------
1270 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1271 # in their respective directory and specialized env.
1272 if frontend in ['qt2', 'qt3']:
1273 # note: env.Tool('qt') my set QT_LIB to qt
1275 frontend_libs = ['qt-mt']
1276 elif frontend == 'qt4':
1277 qt_libs = ['QtCore', 'QtGui']
1278 # set the right lib names
1279 if platform_name == 'win32':
1280 if mode == 'debug' and use_vc:
1281 qt_lib_suffix = 'd4'
1286 qt_lib_suffix = '_debug'
1289 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1292 if platform_name in ['win32', 'cygwin']:
1293 # the final link step needs stdc++ to succeed under mingw
1294 # FIXME: shouldn't g++ automatically link to stdc++?
1296 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1298 system_libs = ['shlwapi', 'stdc++', 'z']
1299 elif platform_name == 'cygwin' and env['X11']:
1300 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1301 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1307 ('HAVE_ICONV', env['ICONV_LIB']),
1308 ('HAVE_LIBGDI32', 'gdi32'),
1309 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1310 ('USE_ASPELL', aspell_lib),
1311 ('USE_ISPELL', 'ispell'),
1312 ('USE_PSPELL', 'pspell'),
1317 system_libs.append(lib[1])
1320 # Build parameters CPPPATH etc
1323 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1326 # boost: for boost header files
1327 # BUILDDIR/common: for config.h
1328 # TOP_SRCDIR/src: for support/* etc
1330 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1332 # Separating boost directories from CPPPATH stops scons from building
1333 # the dependency tree for boost header files, and effectively reduce
1334 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1335 # boost headers, this is only done for system boost headers.
1337 env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1340 env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1342 env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1344 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1345 if env['nls'] and included_gettext:
1346 env['CPPPATH'].append('$BUILDDIR/intl')
1348 # QT_INC_PATH is not needed for *every* source file
1349 env['CPPPATH'].remove(qt_inc_path)
1352 # A Link script for cygwin see
1353 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1354 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1357 if platform_name == 'cygwin':
1358 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1359 ld_script = utils.installCygwinLDScript(ld_script_path)
1360 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1361 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1366 # fill in the version info
1367 env['VERSION_INFO'] = '''Configuration
1369 Special build flags: %s
1371 C Compiler flags: %s %s
1373 C++ Compiler LyX flags: %s
1374 C++ Compiler flags: %s %s
1376 Linker user flags: %s
1378 Builing directory: %s
1379 Local library directory: %s
1382 Frontend libraries: %s
1383 System libraries: %s
1384 include search path: %s
1390 ''' % (platform_name,
1391 env.subst('$CCFLAGS'), env.subst('$CC'),
1392 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1393 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1394 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1395 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1396 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1397 str(env['LIBPATH']), str(boost_libraries),
1398 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1399 frontend, packaging_method,
1400 prefix, env['LYX_DIR'])
1402 if frontend in ['qt2', 'qt3', 'qt4']:
1403 env['VERSION_INFO'] += ''' include dir: %s
1406 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1409 print env['VERSION_INFO']
1412 # Mingw command line may be too short for our link usage,
1413 # Here we use a trick from scons wiki
1414 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1416 # I also would like to add logging (commands only) capacity to the
1418 logfile = env.get('logfile', default_log_file)
1419 if logfile != '' or platform_name == 'win32':
1421 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1422 info = '''# This is a log of commands used by scons to build lyx
1426 ''' % (time.asctime(), ' '.join(sys.argv),
1427 env['VERSION_INFO'].replace('\n','\n# ')) )
1432 # -h will print out help info
1433 Help(opts.GenerateHelpText(env))
1435 # save environment settings (for fast_start option)
1436 cache_file = open(env_cache_file, 'w')
1437 cPickle.dump(env_cache, cache_file)
1441 #----------------------------------------------------------
1443 #----------------------------------------------------------
1444 # this has been the source of problems on some platforms...
1445 # I find that I need to supply it with full path name
1446 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1447 # this usage needs further investigation.
1448 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1450 print "Building all targets recursively"
1452 if env.has_key('rebuild'):
1453 rebuild_targets = env['rebuild'].split(',')
1455 rebuild_targets = None
1457 def libExists(libname):
1458 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1459 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1461 targets = BUILD_TARGETS
1462 # msvc need to pass full target name, so I have to look for path/lyx etc
1463 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1464 or 'install' in targets or 'all' in targets
1465 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1466 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1467 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1468 build_mathed = build_lyx or 'mathed' in targets
1469 build_insets = build_lyx or 'insets' in targets
1470 build_frontends = build_lyx or 'frontends' in targets
1471 build_graphics = build_lyx or 'graphics' in targets
1472 build_controllers = build_lyx or 'controllers' in targets
1473 build_client = True in ['client' in x for x in targets] \
1474 or 'install' in targets or 'all' in targets
1475 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1476 or 'install' in targets or 'all' in targets
1477 build_lyxbase = build_lyx or 'lyxbase' in targets
1478 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1479 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1480 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1481 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1482 build_msvs_projects = use_vc and 'msvs_projects' in targets
1485 # now, if rebuild_targets is specified, do not rebuild some targets
1486 rebuild_targets = rebuild_targets
1488 def ifBuildLib(name, libname, old_value):
1489 # explicitly asked to rebuild
1490 if name in rebuild_targets:
1492 # else if not rebuild, and if the library already exists
1493 elif libExists(libname):
1495 # do not change the original value
1498 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1499 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1500 build_support = ifBuildLib('support', 'support', build_support)
1501 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1502 build_insets = ifBuildLib('insets', 'insets', build_insets)
1503 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1504 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1505 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1506 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1507 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1508 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1509 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1511 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1525 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1527 boostenv = env.Copy()
1529 # boost use its own config.h
1530 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1531 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1533 for lib in boost_libs:
1534 print 'Processing files in boost/libs/%s/src...' % lib
1535 boostlib = boostenv.StaticLibrary(
1536 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1537 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1538 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1540 Alias('boost', boostlib)
1547 intlenv = env.Copy()
1549 print "Processing files in intl..."
1551 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1553 # we need the original C compiler for these files
1554 intlenv['CC'] = C_COMPILER
1555 intlenv['CCFLAGS'] = C_CCFLAGS
1557 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1558 # intl does not use global config.h
1559 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1561 intlenv.Append(CCFLAGS = [
1562 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1563 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1564 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1566 '-DENABLE_RELOCATABLE=1',
1568 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1570 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1571 '-Drelocate=libintl_relocate',
1572 '-DDEPENDS_ON_LIBICONV=1',
1577 intl = intlenv.StaticLibrary(
1578 target = '$LOCALLIBPATH/included_intl',
1580 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1581 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1582 build_dir = '$BUILDDIR/intl')
1588 # Now, src code under src/
1590 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1597 print "Processing files in src/support..."
1599 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1601 support = env.StaticLibrary(
1602 target = '$LOCALLIBPATH/support',
1603 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1604 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1605 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1607 Alias('support', support)
1614 print "Processing files in src/mathed..."
1616 mathed = env.StaticLibrary(
1617 target = '$LOCALLIBPATH/mathed',
1618 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1620 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1621 build_dir = '$BUILDDIR/common/mathed')
1623 Alias('mathed', mathed)
1630 print "Processing files in src/insets..."
1632 insets = env.StaticLibrary(
1633 target = '$LOCALLIBPATH/insets',
1634 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1636 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1638 Alias('insets', insets)
1645 print "Processing files in src/frontends..."
1647 frontends = env.StaticLibrary(
1648 target = '$LOCALLIBPATH/frontends',
1649 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1650 build_dir = '$BUILDDIR/common/frontends')
1652 Alias('frontends', frontends)
1659 print "Processing files in src/graphics..."
1661 graphics = env.StaticLibrary(
1662 target = '$LOCALLIBPATH/graphics',
1663 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1664 build_dir = '$BUILDDIR/common/graphics')
1666 Alias('graphics', graphics)
1669 if build_controllers:
1671 # src/frontends/controllers
1673 print "Processing files in src/frontends/controllers..."
1675 controllers = env.StaticLibrary(
1676 target = '$LOCALLIBPATH/controllers',
1677 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1678 build_dir = '$BUILDDIR/common/frontends/controllers')
1680 Alias('controllers', controllers)
1684 # src/frontend/qt2/3/4
1686 if build_qt2 or build_qt3 or build_qt4:
1687 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1691 print "Processing files in src/frontends/qt2..."
1694 # disable auto scan to speed up non build time
1695 qt2env['QT_AUTOSCAN'] = 0
1696 qt2env['QT_MOCHPREFIX'] = ''
1701 qt2env.AppendUnique(CPPPATH = [
1703 '$BUILDDIR/common/images',
1704 '$BUILDDIR/common/frontends',
1705 '$BUILDDIR/common/frontends/qt2',
1706 '$BUILDDIR/common/frontends/controllers',
1710 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1713 FileDialog_private.C
1752 QSpellcheckerDialog.C
1754 QTabularCreateDialog.C
1769 # manually moc and uic files for better performance
1770 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1772 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1773 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1775 qt2_uiced_cc_files = []
1776 for x in qt2_uiced_files:
1777 qt2_uiced_cc_files.extend(x[1:])
1779 qt2 = qt2env.StaticLibrary(
1780 target = '$LOCALLIBPATH/qt2',
1781 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1782 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1788 print "Processing files in src/frontends/qt3..."
1791 # disable auto scan to speed up non build time
1792 qt3env['QT_AUTOSCAN'] = 0
1793 qt3env['QT_MOCHPREFIX'] = ''
1798 qt3env.AppendUnique(CPPPATH = [
1800 '$BUILDDIR/common/images',
1801 '$BUILDDIR/common/frontends',
1802 '$BUILDDIR/common/frontends/qt3',
1803 '$BUILDDIR/common/frontends/controllers',
1807 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1810 FileDialog_private.C
1850 QSpellcheckerDialog.C
1852 QTabularCreateDialog.C
1867 # manually moc and uic files for better performance
1868 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1870 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1871 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1873 qt3_uiced_cc_files = []
1874 for x in qt3_uiced_files:
1875 qt3_uiced_cc_files.extend(x[1:])
1877 qt3 = qt3env.StaticLibrary(
1878 target = '$LOCALLIBPATH/qt3',
1879 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1880 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1886 print "Processing files in src/frontends/qt4..."
1889 qt4env['QT_AUTOSCAN'] = 0
1891 # local qt4 toolset from
1892 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1894 # NOTE: I have to patch qt4.py since it does not automatically
1895 # process .C file!!! (add to cxx_suffixes )
1897 qt4env.Tool('qt4', [scons_dir])
1898 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1900 qt4env.AppendUnique(CPPPATH = [
1902 '$BUILDDIR/common/images',
1903 '$BUILDDIR/common/frontends',
1904 '$BUILDDIR/common/frontends/qt4',
1905 '$BUILDDIR/common/frontends/controllers',
1910 # FIXME: replace by something from pkg_config
1911 qt4env.Append(CCFLAGS = [
1913 '-DQT_CLEAN_NAMESPACE',
1921 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1924 FileDialog_private.C
1967 QSpellcheckerDialog.C
1969 QTabularCreateDialog.C
1988 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1989 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1990 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1993 # moc qt4_moc_files, the moced files are included in the original files
1995 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1997 qt4 = qt4env.StaticLibrary(
1998 target = '$LOCALLIBPATH/qt4',
1999 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
2000 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
2009 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
2011 print "Processing files in src/client..."
2013 if env['HAVE_FCNTL']:
2014 client = env.Program(
2015 target = '$BUILDDIR/common/client/lyxclient',
2016 LIBS = ['support'] + intl_libs + system_libs +
2017 socket_libs + boost_libraries,
2018 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
2019 build_dir = '$BUILDDIR/common/client')
2021 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
2022 client, [Copy('$TARGET', '$SOURCE')]))
2025 Alias('client', client)
2032 print "Processing files in src/tex2lyx..."
2034 tex2lyx_env = env.Copy()
2036 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2037 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2039 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2040 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2041 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2042 [Copy('$TARGET', '$SOURCE')])
2044 tex2lyx = tex2lyx_env.Program(
2045 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2046 LIBS = ['support'] + boost_libraries + system_libs,
2047 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2048 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2049 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2050 build_dir = '$BUILDDIR/common/tex2lyx')
2052 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2053 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2054 Alias('tex2lyx', tex2lyx)
2061 print "Processing files in src..."
2063 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2065 lyx_post_source = Split('''
2074 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2075 lyx_post_source.append('aspell.C')
2076 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2077 lyx_post_source.append('pspell.C')
2078 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2079 lyx_post_source.append('ispell.C')
2081 # msvc requires at least one source file with main()
2082 # so I exclude main.C from lyxbase
2083 lyxbase_pre = env.StaticLibrary(
2084 target = '$LOCALLIBPATH/lyxbase_pre',
2085 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2086 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2087 'ispell.C', 'Variables.C', 'Sectioning.C'],
2088 include = ['version.C'], build_dir = '$BUILDDIR/common')
2090 lyxbase_post = env.StaticLibrary(
2091 target = '$LOCALLIBPATH/lyxbase_post',
2092 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2094 Alias('lyxbase', lyxbase_pre)
2095 Alias('lyxbase', lyxbase_post)
2100 # Build lyx with given frontend
2103 target = '$BUILDDIR/$frontend/lyx',
2104 source = ['$BUILDDIR/common/main.C'],
2122 # [/path/to/lyx.ext] => lyx-qt3.ext
2123 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2124 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2125 [Copy('$TARGET', '$SOURCE')]))
2129 if build_msvs_projects:
2130 def build_project(target, dir, full_target = None,
2131 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2132 ''' build mavs project files
2133 target: alias (correspond to directory name)
2134 dir: source directory or directories (a list)
2135 full_target: full path/filename of the target
2136 src_pattern: glob pattern
2137 include: files to include into source
2138 resource: directory or directories with resource (.ui) files
2139 rebuildTargetOnly: whether or not only rebuild this target
2141 For non-debug-able targets like static libraries, target (alias) is
2142 enough to build the target. For executable targets, msvs need to know
2143 the full path to start debug them.
2145 if resource is not None:
2146 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2147 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2150 if rebuildTargetOnly:
2151 cmds = 'faststart=yes rebuild='+target
2153 cmds = 'faststart=yes'
2154 if type(dir) == type([]):
2158 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2159 pattern = src_pattern, include = include,
2160 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2161 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2163 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2165 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2166 pattern = src_pattern, include = include,
2167 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2168 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2170 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2171 if full_target is None:
2172 build_target = target
2174 build_target = full_target
2176 proj = env.MSVSProject(
2177 target = target + env['MSVSPROJECTSUFFIX'],
2179 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2182 buildtarget = build_target,
2186 Alias('msvs_projects', proj)
2188 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2189 src_pattern = '*.cpp')
2191 build_project('intl', 'intl', src_pattern = '*.c')
2193 build_project('support', 'src/support', include=['package.C.in'])
2195 build_project('mathed', 'src/mathed')
2197 build_project('insets', 'src/insets')
2199 build_project('frontends', 'src/frontends')
2201 build_project('graphics', 'src/graphics')
2203 build_project('controllers', 'src/frontends/controllers')
2205 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2207 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2209 build_project('client', 'src/client', rebuildTargetOnly = False,
2210 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2212 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2213 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2215 build_project('lyxbase', 'src')
2217 if frontend == 'qt3':
2218 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2219 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2220 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2221 rebuildTargetOnly = False,
2222 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2224 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2225 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2226 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2227 rebuildTargetOnly = False,
2228 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2235 print 'Processing files in po...'
2240 # files to translate
2241 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2242 # possibly *only* handle these languages
2244 if env.has_key('languages'):
2245 languages = env.make_list(env['lanauges'])
2246 # use defulat msgfmt
2247 if not env['MSGFMT']:
2248 print 'msgfmt does not exist. Can not process po files'
2251 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2254 for f in transfiles:
2256 fname = os.path.split(f)[1]
2258 country = fname.split('.')[0]
2260 if not languages or country in languages:
2261 gmo_files.extend(env.Transfiles(f))
2264 if 'install' in targets:
2266 # install to DESTDIR or prefix
2267 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2268 # if dest_dir is different from prefix.
2269 if env.has_key('exec_prefix'):
2270 bin_dest_dir = Dir(env['exec_prefix']).abspath
2272 bin_dest_dir = os.path.join(dest_dir, 'bin')
2274 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2276 share_dest_dir = os.path.join(dest_dir, share_dir)
2277 man_dest_dir = os.path.join(dest_dir, man_dir)
2278 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2279 # create the directory if needed
2280 if not os.path.isdir(dest_dir):
2282 os.makedirs(dest_dir)
2285 if not os.path.isdir(dest_dir):
2286 print 'Can not create directory', dest_dir
2291 # do not install these files
2292 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2293 'lyx2lyx_version.py.in']
2295 def install(dest, src):
2296 ''' recusive installation of src to dest '''
2297 # separate file and directory
2298 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2299 dirs = filter(os.path.isdir, src)
2301 env.Install(dest, files)
2305 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2306 glob.glob(os.path.join(dir, '*'))) )
2309 # executables (some of them may be none)
2312 version_suffix = program_suffix
2317 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2318 target = os.path.join(bin_dest_dir, target_name)
2319 env.InstallAs(target, lyx)
2320 Alias('install', target)
2321 # install lyx as lyx-qt3
2322 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2323 target = os.path.join(bin_dest_dir, target_name)
2324 env.InstallAs(target, lyx)
2325 Alias('install', target)
2328 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2329 target = os.path.join(bin_dest_dir, target_name)
2330 env.InstallAs(target, tex2lyx)
2331 Alias('install', target)
2333 # install lyxclient, may not exist
2335 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2336 target = os.path.join(bin_dest_dir, target_name)
2337 env.InstallAs(target, client)
2338 Alias('install', target)
2341 dirs = install(share_dest_dir,
2342 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2343 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2344 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2345 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2347 # lyx1.4.x does not have lyx2lyx_version.py.in
2348 if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2349 # subst and install this file
2350 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2351 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2352 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2353 Alias('install', dirs)
2355 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2356 env.subst('$TOP_SRCDIR/lyx.man'))
2357 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2358 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2359 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2360 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2361 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2362 x in ['lyx', 'tex2lyx', 'lyxclient']])
2364 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2365 for gmo in gmo_files:
2366 lan = os.path.split(str(gmo))[1].split('.')[0]
2367 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2368 env.InstallAs(dest_file, gmo)
2369 Alias('install', dest_file)
2373 Alias('all', ['lyx', 'client', 'tex2lyx'])