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'
53 package_version = '1.5.0svn'
56 default_build_mode = 'debug'
60 package_bugreport = 'lyx-devel@lists.lyx.org'
62 package_tarname = 'lyx'
63 package_string = '%s %s' % (package_name, package_version)
65 # various cache/log files
66 default_log_file = 'scons_lyx.log'
67 env_cache_file = 'env.cache'
70 #----------------------------------------------------------
71 # platform dependent settings
72 #----------------------------------------------------------
75 platform_name = 'win32'
76 default_frontend = 'qt4'
77 default_prefix = 'c:/program files/lyx'
78 default_with_x = False
79 default_packaging_method = 'windows'
80 elif os.name == 'posix' and sys.platform != 'cygwin':
81 platform_name = sys.platform
82 default_frontend = 'qt3'
83 default_prefix = '/usr/local'
85 default_packaging_method = 'posix'
86 elif os.name == 'posix' and sys.platform == 'cygwin':
87 platform_name = 'cygwin'
88 default_frontend = 'qt3'
89 default_prefix = '/usr/local'
91 default_packaging_method = 'posix'
92 elif os.name == 'darwin':
93 platform_name = 'macosx'
94 default_frontend = 'qt3'
95 # FIXME: macOSX default prefix?
97 default_with_x = False
98 default_packaging_method = 'macosx'
99 else: # unsupported system, assume posix behavior
100 platform_name = 'others'
101 default_frontend = 'qt3'
103 default_with_x = True
104 default_packaging_method = 'posix'
106 # 1.4.2 only has qt2 frontend
107 if package_version == '1.4.2svn':
108 default_frontend = 'qt2'
110 #---------------------------------------------------------
112 #----------------------------------------------------------
114 # You can set perminant default values in config.py
115 if os.path.isfile('config.py'):
116 print "Getting options from config.py..."
117 print open('config.py').read()
119 opts = Options(['config.py'])
122 EnumOption('frontend', 'Main GUI', default_frontend,
123 allowed_values = ('xform', 'qt2', 'qt3', 'qt4', 'gtk') ),
124 # debug or release build
125 EnumOption('mode', 'Building method', default_build_mode,
126 allowed_values = ('debug', 'release') ),
129 'Use included, system boost library, or try sytem boost first.',
130 'auto', allowed_values = (
131 'auto', # detect boost, if not found, use included
132 'included', # always use included boost
133 'system', # always use system boost, fail if can not find
136 EnumOption('gettext',
137 'Use included, system gettext library, or try sytem gettext first',
138 'auto', allowed_values = (
139 'auto', # detect gettext, if not found, use included
140 'included', # always use included gettext
141 'system', # always use system gettext, fail if can not find
144 EnumOption('spell', 'Choose spell checker to use.', 'auto',
145 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
147 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
148 allowed_values = ('windows', 'posix', 'macosx')),
150 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
151 # No precompiled header support (too troublesome to make it work for msvc)
152 # BoolOption('pch', 'Whether or not use pch', False),
153 # enable assertion, (config.h has ENABLE_ASSERTIOS
154 BoolOption('assertions', 'Use assertions', True),
155 # enable warning, (config.h has WITH_WARNINGS)
156 # default to False since MSVC does not have #warning
157 BoolOption('warnings', 'Use warnings', False),
158 # config.h define _GLIBCXX_CONCEPT_CHECKS
159 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
160 BoolOption('concept_checks', 'Enable concept checks', True),
162 BoolOption('nls', 'Whether or not use native language support', True),
164 BoolOption('profiling', 'Whether or not enable profiling', False),
165 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
166 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
168 BoolOption('X11', 'Use x11 windows system', default_with_x),
169 # use MS VC++ to build lyx
170 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
172 PathOption('qt_dir', 'Path to qt directory', None),
174 PathOption('qt_inc_path', 'Path to qt include directory', None),
176 PathOption('qt_lib_path', 'Path to qt library directory', None),
177 # build directory, will use $mode if not set
178 PathOption('build_dir', 'Build 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),
194 ('version_suffix', 'install lyx as lyx-suffix', None),
195 # how to load options
196 ('load_option', '''load option from previous scons run. option can be
197 yes (default): load all options
198 no: do not load any option
199 opt1,opt2: load specified options
200 -opt1,opt2: load all options other than specified ones''', 'yes'),
202 ('optimization', 'optimization CCFLAGS option.', None),
204 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
206 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
207 # provided for backward compatibility
208 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
209 # environment variable can be set as options.
210 ('DESTDIR', 'install to DESTDIR', None),
211 ('CC', 'replace default $CC', None),
212 ('LINK', 'replace default $LINK', None),
213 ('CPP', 'replace default $CPP', None),
214 ('CXX', 'replace default $CXX', None),
215 ('CXXCPP', 'replace default $CXXCPP', None),
216 ('CCFLAGS', 'replace default $CCFLAGS', None),
217 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
218 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
221 # copied from SCons/Options/BoolOption.py
222 # We need to use them before a boolean ARGUMENTS option is available
224 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
225 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
227 # whether or not use current config.h, and cached tests
229 # if fast_start=yes (default), load variables from env_cache_file
230 if (not ARGUMENTS.has_key('fast_start') or \
231 ARGUMENTS['fast_start'] in true_strings) \
232 and os.path.isfile(env_cache_file):
234 cache_file = open(env_cache_file)
235 env_cache = cPickle.load(cache_file)
237 print '------------ fast_start mode --------------------'
238 print ' Use cached test results and current config.h'
239 print ' use fast_start=no to override'
245 # if load_option=yes (default), load saved comand line options
247 # This option can take value yes/no/opt1,opt2/-opt1,opt2
248 # and tries to be clever in choosing options to load
249 if (not ARGUMENTS.has_key('load_option') or \
250 ARGUMENTS['load_option'] not in false_strings) \
251 and os.path.isfile(env_cache_file):
252 cache_file = open(env_cache_file)
253 opt_cache = cPickle.load(cache_file)['arg_cache']
255 # import cached options, but we should ignore qt_dir when frontend changes
256 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
257 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
258 and opt_cache.has_key('qt_dir'):
259 opt_cache.pop('qt_dir')
260 # some options will require full rebuild
261 # these are in general things that will change config.h
262 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
263 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
264 ARGUMENTS[arg] != opt_cache[arg]):
266 print " ** fast_start is disabled because of the change of option", arg
269 # and we do not cache some options
270 for arg in ['fast_start', 'load_option']:
271 if opt_cache.has_key(arg):
273 # now, if load_option=opt1,opt2 or -opt1,opt2
274 if ARGUMENTS.has_key('load_option') and \
275 ARGUMENTS['load_option'] not in true_strings + false_strings:
276 # if -opt1,opt2 is specified, do not load these options
277 if ARGUMENTS['load_option'][0] == '-':
278 for arg in ARGUMENTS['load_option'][1:].split(','):
279 if opt_cache.has_key(arg):
281 # if opt1,opt2 is specified, only load specified options
283 args = ARGUMENTS['load_option'].split(',')
284 for arg in opt_cache.keys():
287 # now restore options as if entered from command line
288 for key in opt_cache.keys():
289 if not ARGUMENTS.has_key(key):
290 ARGUMENTS[key] = opt_cache[key]
291 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
295 env_cache['arg_cache'] = ARGUMENTS
298 #---------------------------------------------------------
299 # Setting up environment
300 #---------------------------------------------------------
302 # I do not really like ENV=os.environ, but you may add it
303 # here if you experience some environment related problem
304 env = Environment(options = opts)
306 # set individual variables since I do not really like ENV = os.environ
307 env['ENV']['PATH'] = os.environ.get('PATH')
308 env['ENV']['HOME'] = os.environ.get('HOME')
309 # these are defined for MSVC
310 env['ENV']['LIB'] = os.environ.get('LIB')
311 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
313 # for simplicity, use var instead of env[var]
314 frontend = env['frontend']
315 prefix = env['prefix']
318 if platform_name == 'win32':
319 if env.has_key('use_vc'):
320 use_vc = env['use_vc']
321 if WhereIs('cl.exe') is None:
322 print "cl.exe is not found. Are you using the MSVC environment?"
324 elif WhereIs('cl.exe') is not None:
331 # lyx will be built to $build/build_dir so it is possible
332 # to build multiple build_dirs using the same source
333 # $mode can be debug or release
334 if env.has_key('build_dir') and env['build_dir'] is not None:
335 env['BUILDDIR'] = env['build_dir']
337 # Determine the name of the build $mode
338 env['BUILDDIR'] = '#' + mode
340 # all built libraries will go to build_dir/libs
341 # (This is different from the make file approach)
342 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
343 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
346 # Here is a summary of variables defined in env
348 # 2. undefined options with a non-None default value
349 # 3. compiler commands and flags like CCFLAGS.
350 # MSGFMT used to process po files
351 # 4. Variables that will be used to replace variables in some_file.in
352 # src/support/package.C.in:
353 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
354 # lib/lyx2lyx/lyx2lyx_version.py.in
357 # PACKAGE_VERSION, VERSION_INFO
358 # src/frontends/xforms/lyx_xpm.h.in
360 # src/frontends/xforms/lyx_forms.h.in
363 # full path name is used to build msvs project files
364 # and to replace TOP_SRCDIR in package.C
365 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
366 # needed by src/version.C.in => src/version.C
367 env['PACKAGE_VERSION'] = package_version
369 # determine share_dir etc
370 packaging_method = env.get('packaging')
371 if packaging_method == 'windows':
372 share_dir = 'Resources'
373 man_dir = 'Resources/man/man1'
374 locale_dir = 'Resources/locale'
375 default_prefix = 'c:/program files/lyx'
377 share_dir = 'share/lyx'
379 locale_dir = 'share/locale'
380 default_prefix = '/usr/local/'
382 # install to default_prefix by default
383 # program suffix: can be yes, or a string
384 if env.has_key('version_suffix'):
385 if env['version_suffix'] in true_strings:
386 program_suffix = package_version
387 elif env['version_suffix'] in false_strings:
390 program_suffix = env['version_suffix']
393 # used by package.C.in
394 env['PROGRAM_SUFFIX'] = program_suffix
396 # whether or not add suffix to file and directory names
397 add_suffix = packaging_method != 'windows'
398 # LYX_DIR are different (used in package.C.in)
400 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
402 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
403 # we need absolute path for package.C
404 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
407 #---------------------------------------------------------
408 # Setting building environment (Tools, compiler flags etc)
409 #---------------------------------------------------------
411 # Since Tool('mingw') will reset CCFLAGS etc, this should be
412 # done before getEnvVariable
413 if platform_name == 'win32':
419 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
421 # we differentiate between hard-coded options and default options
422 # hard-coded options are required and will always be there
423 # default options can be replaced by enviromental variables or command line options
424 CCFLAGS_required = []
425 LINKFLAGS_required = []
428 # under windows, scons is confused by .C/.c and uses gcc instead of
429 # g++. I am forcing the use of g++ here. This is expected to change
430 # after lyx renames all .C files to .cpp
432 # save the old c compiler and CCFLAGS (used by libintl)
433 C_COMPILER = env.subst('$CC')
434 C_CCFLAGS = env.subst('$CCFLAGS').split()
435 # if we use ms vc, the commands are fine (cl.exe and link.exe)
437 # /TP treat all source code as C++
438 # C4819: The file contains a character that cannot be represented
439 # in the current code page (number)
440 # C4996: foo was decleared deprecated
441 CCFLAGS_required.extend(['/TP', '/EHsc'])
442 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
444 if env.has_key('CXX') and env['CXX']:
445 env['CC'] = env.subst('$CXX')
446 env['LINK'] = env.subst('$CXX')
451 # for debug/release mode
452 if env.has_key('optimization') and env['optimization'] is not None:
453 # if user supplies optimization flags, use it anyway
454 CCFLAGS_required.extend(env['optimization'].split())
455 # and do not use default
456 set_default_optimization_flags = False
458 set_default_optimization_flags = True
462 CCFLAGS_required.append('/Zi')
463 LINKFLAGS_required.extend(['/debug', '/map'])
465 CCFLAGS_required.append('-g')
466 CCFLAGS_default.append('-O')
467 elif mode == 'release' and set_default_optimization_flags:
469 CCFLAGS_default.append('/O2')
471 CCFLAGS_default.append('-O2')
473 # msvc uses separate tools for profiling
474 if env.has_key('profiling') and env['profiling']:
476 print 'Visual C++ does not use profiling options'
478 CCFLAGS_required.append('-pg')
479 LINKFLAGS_required.append('-pg')
481 if env.has_key('warnings') and env['warnings']:
483 CCFLAGS_default.append('/W2')
485 # Note: autotools detect gxx version and pass -W for 3.x
486 # and -Wextra for other versions of gcc
487 CCFLAGS_default.append('-Wall')
489 # Now, set the variables as follows:
490 # 1. if command line option exists: replace default
491 # 2. then if s envronment variable exists: replace default
492 # 3. set variable to required + default
493 def setEnvVariable(env, name, required = None, default = None, split = True):
494 ''' env: environment to set variable
496 required: hardcoded options
497 default: default options that can be replaced by command line or
498 environment variables
499 split: whether or not split obtained variable like '-02 -g'
501 # first try command line argument (override environment settings)
502 if ARGUMENTS.has_key(name):
503 default = ARGUMENTS[name]
505 default = default.split()
506 # then use environment default
507 elif os.environ.has_key(name):
508 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
509 default = os.environ[name]
511 default = default.split()
513 if required is not None:
515 if default is not None:
516 if env.has_key(name) and env[name] != default:
521 setEnvVariable(env, 'DESTDIR', split=False)
522 setEnvVariable(env, 'CC')
523 setEnvVariable(env, 'LINK')
524 setEnvVariable(env, 'CPP')
525 setEnvVariable(env, 'CXX')
526 setEnvVariable(env, 'CXXCPP')
527 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
528 setEnvVariable(env, 'CXXFLAGS')
529 setEnvVariable(env, 'CPPFLAGS')
530 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
532 # if DESTDIR is not set...
533 if env.has_key('dest_dir'):
534 print "This option is obsolete. Please use DESTDIR instead."
535 env['DESTDIR'] = env['dest_dir']
538 #---------------------------------------------------------
539 # Frontend related variables (QTDIR etc)
540 #---------------------------------------------------------
542 if env.has_key('qt_dir') and env['qt_dir']:
543 env['QTDIR'] = env['qt_dir']
544 # add path to the qt tools
545 env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
546 # set environment so that moc etc can be found even if its path is not set properly
547 env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
548 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
549 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
551 if env.has_key('qt_lib_path') and env['qt_lib_path']:
552 qt_lib_path = env.subst('$qt_lib_path')
553 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
554 qt_lib_path = env.subst('$QTDIR/lib')
555 # this is the path for cygwin.
556 elif os.path.isdir(os.path.join('/usr/lib/', frontend, 'lib')):
557 qt_lib_path = env.subst('/usr/lib/$frontend/lib')
559 print "Qt library directory is not found. Please specify it using qt_lib_path"
561 env.AppendUnique(LIBPATH = [qt_lib_path])
562 # qt4 seems to be using pkg_config
563 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
565 if env.has_key('qt_inc_path') and env['qt_inc_path']:
566 qt_inc_path = env['qt_inc_path']
567 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
568 qt_inc_path = '$QTDIR/include'
569 # this is the path for cygwin.
570 elif os.path.isdir('/usr/include/' + frontend):
571 qt_inc_path = '/usr/include/$frontend'
573 print "Qt include directory not found. Please specify it using qt_inc_path"
575 # Note that this CPPPATH is for testing only
576 # it will be removed before calling SConscript
577 env['CPPPATH'] = [qt_inc_path]
580 # extra_inc_path and extra_lib_path
583 if env.has_key('extra_inc_path') and env['extra_inc_path']:
584 extra_inc_paths.append(env['extra_inc_path'])
585 if env.has_key('extra_lib_path') and env['extra_lib_path']:
586 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
587 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
588 extra_inc_paths.append(env['extra_inc_path1'])
589 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
590 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
591 if env.has_key('extra_bin_path') and env['extra_bin_path']:
592 # maybe only one of them is needed
593 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
594 env['ENV']['PATH'] += os.pathsep + env['extra_bin_path']
595 # extra_inc_paths will be used later by intlenv etc
596 env.AppendUnique(CPPPATH = extra_inc_paths)
599 #----------------------------------------------------------
601 #----------------------------------------------------------
603 conf = Configure(env,
605 'CheckPkgConfig' : utils.checkPkgConfig,
606 'CheckPackage' : utils.checkPackage,
607 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
608 'CheckSelectArgType' : utils.checkSelectArgType,
609 'CheckBoostLibraries' : utils.checkBoostLibraries,
610 'CheckCommand' : utils.checkCommand,
611 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
612 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
613 'CheckIconvConst' : utils.checkIconvConst,
617 # pkg-config? (if not, we use hard-coded options)
619 if conf.CheckPkgConfig('0.15.0'):
620 env['HAS_PKG_CONFIG'] = True
622 print 'pkg-config >= 0.1.50 is not found'
623 env['HAS_PKG_CONFIG'] = False
624 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
626 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
628 # zlib? This is required. (fast_start assumes the existance of zlib)
630 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
631 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
632 print 'Did not find zdll.lib or zlib.h, exiting!'
638 # qt3 does not use pkg_config
639 if frontend in ['qt2', 'qt3']:
640 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
641 print 'Did not find qt libraries, exiting!'
643 elif frontend == 'qt4':
645 # first: try pkg_config
646 if env['HAS_PKG_CONFIG']:
647 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
648 # FIXME: use pkg_config information?
649 #env['QT4_PKG_CONFIG'] = succ
650 # second: try to link to it
652 # Under linux, I can test the following perfectly
653 # Under windows, lib names need to passed as libXXX4.a ...
654 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
655 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
656 # third: try to look up the path
659 for lib in ['QtCore', 'QtGui']:
660 # windows version has something like QtGui4 ...
661 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
662 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
665 # still can not find it
667 print "Qt4 libraries are found."
669 print 'Did not find qt libraries, exiting!'
672 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
675 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
677 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
678 if os.path.isfile(manifest):
679 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
684 if conf.CheckLib('socket'):
685 socket_libs.append('socket')
686 # nsl is the network services library and provides a
687 # transport-level interface to networking services.
688 if conf.CheckLib('nsl'):
689 socket_libs.append('nsl')
690 env_cache['SOCKET_LIBS'] = socket_libs
692 socket_libs = env_cache['SOCKET_LIBS']
694 # check available boost libs (since lyx1.4 does not use iostream)
696 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
697 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
698 boost_libs.append(lib)
701 # check boost libraries
702 boost_opt = ARGUMENTS.get('boost', 'auto')
703 # check for system boost
704 paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
705 # real libraries (included or system)
708 # here I assume that all libraries are in the same directory
709 for lib in boost_libs:
710 if boost_opt == 'included':
711 boost_libraries.append('included_boost_%s' % lib)
712 env['INCLUDED_BOOST'] = True
713 elif boost_opt == 'auto':
714 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
717 boost_libraries.append('included_boost_%s' % lib)
718 env['INCLUDED_BOOST'] = True
720 boost_libraries.append(res[1])
721 env['INCLUDED_BOOST'] = False
722 boost_libpath = res[0]
723 elif boost_opt == 'system':
724 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
726 print "Can not find system boost libraries"
727 print "Please supply a path through extra_lib_path and try again."
728 print "Or use boost=included to use included boost libraries."
731 boost_libraries.append(res[1])
732 env.AppendUnique(LIBPATH = [res[0]])
733 boost_libpath = res[0]
734 env_cache['BOOST_LIBRARIES'] = boost_libraries
735 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
736 env_cache['BOOST_LIBPATH'] = boost_libpath
738 boost_libraries = env_cache['BOOST_LIBRARIES']
739 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
740 boost_libpath = env_cache['BOOST_LIBPATH']
742 if boost_libpath is not None:
743 env.AppendUnique(LIBPATH = [boost_libpath])
746 env['ENABLE_NLS'] = env['nls']
749 if not env['ENABLE_NLS']:
751 included_gettext = False
753 # check gettext libraries
754 gettext_opt = ARGUMENTS.get('gettext', 'auto')
755 # check for system gettext
757 if gettext_opt in ['auto', 'system']:
758 if conf.CheckLib('intl'):
759 included_gettext = False
763 if gettext_opt == 'system':
764 print "Can not find system gettext library"
765 print "Please supply a path through extra_lib_path and try again."
766 print "Or use gettext=included to use included gettext libraries."
768 # now, auto and succ = false, or gettext=included
770 # we do not need to set LIBPATH now.
771 included_gettext = True
772 intl_libs = ['included_intl']
773 env_cache['INCLUDED_GETTEXT'] = included_gettext
774 env_cache['INTL_LIBS'] = intl_libs
776 included_gettext = env_cache['INCLUDED_GETTEXT']
777 intl_libs = env_cache['INTL_LIBS']
780 # check for msgfmt command
782 env['MSGFMT'] = conf.CheckCommand('msgfmt')
783 env_cache['MSGFMT'] = env['MSGFMT']
785 env['MSGFMT'] = env_cache['MSGFMT']
787 # check uic and moc commands for qt frontends
789 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
790 or conf.CheckCommand('moc') == None):
791 print 'uic or moc command is not found for frontend', frontend
795 # Customized builders
797 # install customized builders
798 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
801 #----------------------------------------------------------
802 # Generating config.h
803 #----------------------------------------------------------
804 aspell_lib = 'aspell'
805 # assume that we use aspell, aspelld compiled for msvc
806 if platform_name == 'win32' and mode == 'debug' and use_vc:
807 aspell_lib = 'aspelld'
809 # check the existence of config.h
810 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
811 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
812 if not fast_start or not os.path.isfile(boost_config_h) \
813 or not os.path.isfile(config_h):
815 print "Creating %s..." % boost_config_h
817 utils.createConfigFile(conf,
818 config_file = boost_config_h,
819 config_pre = '''/* boost/config.h. Generated by SCons. */
824 * This file is part of LyX, the document processor.
825 * Licence details can be found in the file COPYING.
827 * This is the compilation configuration file for LyX.
828 * It was generated by scon.
829 * You might want to change some of the defaults if something goes wrong
830 * during the compilation.
833 #ifndef _BOOST_CONFIG_H
834 #define _BOOST_CONFIG_H
837 ('ostream', 'HAVE_OSTREAM', 'cxx'),
838 ('locale', 'HAVE_LOCALE', 'cxx'),
839 ('sstream', 'HAVE_SSTREAM', 'cxx'),
840 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
843 (env.has_key('assertions') and env['assertions'],
845 'Define if you want assertions to be enabled in the code'
850 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
851 # define USE_BOOST_FORMAT 1
853 # define USE_BOOST_FORMAT 0
856 #if !defined(ENABLE_ASSERTIONS)
857 # define BOOST_DISABLE_ASSERTS 1
859 #define BOOST_ENABLE_ASSERT_HANDLER 1
861 #define BOOST_DISABLE_THREADS 1
862 #define BOOST_NO_WREGEX 1
863 #define BOOST_NO_WSTRING 1
866 # define BOOST_POSIX 1
869 #define BOOST_ALL_NO_LIB 1
871 #if defined(HAVE_NEWAPIS_H)
872 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
879 print "\nGenerating %s..." % config_h
881 # AIKSAURUS_H_LOCATION
882 if (conf.CheckCXXHeader("Aiksaurus.h")):
883 aik_location = '<Aiksaurus.h>'
884 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
885 aik_location = '<Aiksaurus/Aiksaurus.h>'
889 # determine headers to use
890 spell_opt = ARGUMENTS.get('spell', 'auto')
891 env['USE_ASPELL'] = False
892 env['USE_PSPELL'] = False
893 env['USE_ISPELL'] = False
894 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
895 spell_engine = 'USE_ASPELL'
896 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
897 spell_engine = 'USE_PSPELL'
898 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
899 spell_engine = 'USE_ISPELL'
903 if spell_engine is not None:
904 env[spell_engine] = True
906 if spell_opt == 'auto':
907 print "Warning: Can not locate any spell checker"
908 elif spell_opt != 'no':
909 print "Warning: Can not locate specified spell checker:", spell_opt
912 # check arg types of select function
913 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
917 result = utils.createConfigFile(conf,
918 config_file = config_h,
919 config_pre = '''/* config.h. Generated by SCons. */
924 * This file is part of LyX, the document processor.
925 * Licence details can be found in the file COPYING.
927 * This is the compilation configuration file for LyX.
928 * It was generated by scon.
929 * You might want to change some of the defaults if something goes wrong
930 * during the compilation.
937 ('io.h', 'HAVE_IO_H', 'c'),
938 ('limits.h', 'HAVE_LIMITS_H', 'c'),
939 ('locale.h', 'HAVE_LOCALE_H', 'c'),
940 ('process.h', 'HAVE_PROCESS_H', 'c'),
941 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
942 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
943 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
944 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
945 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
946 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
947 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
948 ('utime.h', 'HAVE_UTIME_H', 'c'),
949 ('direct.h', 'HAVE_DIRECT_H', 'c'),
950 ('istream', 'HAVE_ISTREAM', 'cxx'),
951 ('ios', 'HAVE_IOS', 'cxx'),
954 ('open', 'HAVE_OPEN', None),
955 ('close', 'HAVE_CLOSE', None),
956 ('popen', 'HAVE_POPEN', None),
957 ('pclose', 'HAVE_PCLOSE', None),
958 ('_open', 'HAVE__OPEN', None),
959 ('_close', 'HAVE__CLOSE', None),
960 ('_popen', 'HAVE__POPEN', None),
961 ('_pclose', 'HAVE__PCLOSE', None),
962 ('getpid', 'HAVE_GETPID', None),
963 ('_getpid', 'HAVE__GETPID', None),
964 ('mkdir', 'HAVE_MKDIR', None),
965 ('_mkdir', 'HAVE__MKDIR', None),
966 ('mktemp', 'HAVE_MKTEMP', None),
967 ('mkstemp', 'HAVE_MKSTEMP', None),
968 ('strerror', 'HAVE_STRERROR', None),
969 ('count', 'HAVE_STD_COUNT', '''
974 return std::count(a, a+5, 'l');
977 ('getcwd', 'HAVE_GETCWD', None),
978 ('setenv', 'HAVE_SETENV', None),
979 ('putenv', 'HAVE_PUTENV', None),
980 ('fcntl', 'HAVE_FCNTL', None),
983 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
984 '#include <streambuf>\n#include <istream>')
987 ('gdi32', 'HAVE_LIBGDI32'),
988 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
989 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
992 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
994 'Define is sys/types.h does not have pid_t',
998 (conf.CheckCXXGlobalCstd(),
1000 'Define if your C++ compiler puts C library functions in the global namespace'
1002 (conf.CheckMkdirOneArg(),
1003 'MKDIR_TAKES_ONE_ARG',
1004 'Define if mkdir takes only one argument.'
1006 (conf.CheckLC_MESSAGES(),
1008 'Define if your <locale.h> file defines LC_MESSAGES.'
1010 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1013 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1015 (env['nls'] and not included_gettext,
1017 'Define to 1 if using system gettext library'
1019 (env.has_key('warnings') and env['warnings'],
1021 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1023 (env.has_key('concept_checks') and env['concept_checks'],
1024 '_GLIBCXX_CONCEPT_CHECKS',
1025 'libstdc++ concept checking'
1027 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1029 'libstdc++ debug mode'
1031 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1032 '_GLIBCXX_DEBUG_PEDANTIC',
1033 'libstdc++ pedantic debug mode'
1035 (os.name != 'nt', 'BOOST_POSIX',
1036 'Indicates to boost which API to use (posix or windows).'
1038 (spell_engine is not None, spell_engine,
1039 'Spell engine to use'
1043 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1045 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1046 'Define to the address where bug reports for this package should be sent.'),
1047 ('#define PACKAGE_NAME "%s"' % package_name,
1048 'Define to the full name of this package.'),
1049 ('#define PACKAGE_STRING "%s"' % package_string,
1050 'Define to the full name and version of this package.'),
1051 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1052 'Define to the one symbol short name of this package.'),
1053 ('#define PACKAGE_VERSION "%s"' % package_version,
1054 'Define to the version of this package.'),
1055 ('#define BOOST_ALL_NO_LIB 1',
1056 'disable automatic linking of boost libraries.'),
1057 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1058 'Packaging method'),
1059 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1060 'Aiksaurus include file'),
1061 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1062 "Define to the type of arg 1 for `select'."),
1063 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1064 "Define to the type of arg 2, 3, 4 for `select'."),
1065 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1066 "Define to the type of arg 5 for `select'."),
1068 config_post = '''/************************************************************
1069 ** You should not need to change anything beyond this point */
1071 #ifndef HAVE_STRERROR
1072 #if defined(__cplusplus)
1075 char * strerror(int n);
1079 #ifndef HAVE_DECL_MKSTEMP
1080 #if defined(__cplusplus)
1087 #include <../boost/config.h>
1093 # these keys are needed in env
1094 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1095 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1096 'ICONV_LIB', 'AIKSAURUS_LIB']:
1097 # USE_ASPELL etc does not go through result
1098 if result.has_key(key):
1099 env[key] = result[key]
1100 env_cache[key] = env[key]
1103 # if nls=yes and gettext=included, create intl/config.h
1104 # intl/libintl.h etc
1106 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1107 if env['nls'] and included_gettext:
1109 print "Creating %s..." % intl_config_h
1111 # create intl/config.h
1112 result = utils.createConfigFile(conf,
1113 config_file = intl_config_h,
1114 config_pre = '''/* intl/config.h. Generated by SCons. */
1119 * This file is part of LyX, the document processor.
1120 * Licence details can be found in the file COPYING.
1122 * This is the compilation configuration file for LyX.
1123 * It was generated by scon.
1124 * You might want to change some of the defaults if something goes wrong
1125 * during the compilation.
1132 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1133 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1134 ('string.h', 'HAVE_STRING_H', 'c'),
1135 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1136 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1137 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1138 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1139 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1140 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1141 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1144 ('getcwd', 'HAVE_GETCWD', None),
1145 ('stpcpy', 'HAVE_STPCPY', None),
1146 ('strcasecmp', 'HAVE_STRCASECMP', None),
1147 ('strdup', 'HAVE_STRDUP', None),
1148 ('strtoul', 'HAVE_STRTOUL', None),
1149 ('alloca', 'HAVE_ALLOCA', None),
1150 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1151 ('mempcpy', 'HAVE_MEMPCPY', None),
1152 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1153 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1154 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1155 ('setlocale', 'HAVE_SETLOCALE', None),
1156 ('tsearch', 'HAVE_TSEARCH', None),
1157 ('getegid', 'HAVE_GETEGID', None),
1158 ('getgid', 'HAVE_GETGID', None),
1159 ('getuid', 'HAVE_GETUID', None),
1160 ('wcslen', 'HAVE_WCSLEN', None),
1161 ('asprintf', 'HAVE_ASPRINTF', None),
1162 ('wprintf', 'HAVE_WPRINTF', None),
1163 ('snprintf', 'HAVE_SNPRINTF', None),
1164 ('printf', 'HAVE_POSIX_PRINTF', None),
1165 ('fcntl', 'HAVE_FCNTL', None),
1168 ('intmax_t', 'HAVE_INTMAX_T', None),
1169 ('long double', 'HAVE_LONG_DOUBLE', None),
1170 ('long long', 'HAVE_LONG_LONG', None),
1171 ('wchar_t', 'HAVE_WCHAR_T', None),
1172 ('wint_t', 'HAVE_WINT_T', None),
1173 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1174 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1177 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1181 (conf.CheckLC_MESSAGES(),
1183 'Define if your <locale.h> file defines LC_MESSAGES.'
1185 (conf.CheckIconvConst(),
1187 'Define as const if the declaration of iconv() needs const.',
1188 '#define ICONV_CONST',
1189 '#define ICONV_CONST const',
1191 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1192 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1194 "Define to 1 if you have the `intmax_t' type."
1196 (env.has_key('nls') and env['nls'],
1198 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1201 config_post = '#endif'
1204 # these keys are needed in env
1205 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1206 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1207 # USE_ASPELL etc does not go through result
1208 if result.has_key(key):
1209 env[key] = result[key]
1210 env_cache[key] = env[key]
1214 # this comes as a big surprise, without this line
1215 # (doing nothing obvious), adding fast_start=yes
1216 # to a build with fast_start=no will result in a rebuild
1217 # Note that the exact header file to check does not matter
1218 conf.CheckCHeader('io.h')
1219 # only a few variables need to be rescanned
1220 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1221 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1222 'ICONV_LIB', 'AIKSAURUS_LIB']:
1223 env[key] = env_cache[key]
1226 if env['nls'] and included_gettext:
1227 # only a few variables need to be rescanned
1228 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1229 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1230 env[key] = env_cache[key]
1232 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1233 if env['nls'] and included_gettext:
1234 # libgnuintl.h.in => libintl.h
1235 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1236 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1237 [Copy('$TARGET', '$SOURCE')])
1240 # Finish auto-configuration
1243 #----------------------------------------------------------
1244 # Now set up our build process accordingly
1245 #----------------------------------------------------------
1250 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1251 # in their respective directory and specialized env.
1252 if frontend in ['qt2', 'qt3']:
1253 # note: env.Tool('qt') my set QT_LIB to qt
1255 frontend_libs = ['qt-mt']
1256 elif frontend == 'qt4':
1257 qt_libs = ['QtCore', 'QtGui']
1258 # set the right lib names
1259 if platform_name == 'win32':
1260 if mode == 'debug' and use_vc:
1261 qt_lib_suffix = 'd4'
1266 qt_lib_suffix = '_debug'
1269 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1272 if platform_name in ['win32', 'cygwin']:
1273 # the final link step needs stdc++ to succeed under mingw
1274 # FIXME: shouldn't g++ automatically link to stdc++?
1276 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1278 system_libs = ['shlwapi', 'stdc++', 'z']
1279 elif platform_name == 'cygwin' and env['X11']:
1280 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1281 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1287 ('HAVE_ICONV', env['ICONV_LIB']),
1288 ('HAVE_LIBGDI32', 'gdi32'),
1289 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1290 ('USE_ASPELL', aspell_lib),
1291 ('USE_ISPELL', 'ispell'),
1292 ('USE_PSPELL', 'pspell'),
1297 system_libs.append(lib[1])
1300 # Build parameters CPPPATH etc
1303 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1306 # boost: for boost header files
1307 # BUILDDIR/common: for config.h
1308 # TOP_SRCDIR/src: for support/* etc
1310 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$BUILDDIR/common', '$TOP_SRCDIR/src']
1311 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1312 if env['nls'] and included_gettext:
1313 env['CPPPATH'].append('$BUILDDIR/intl')
1315 # QT_INC_PATH is not needed for *every* source file
1316 env['CPPPATH'].remove(qt_inc_path)
1319 # A Link script for cygwin see
1320 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1321 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1324 if platform_name == 'cygwin':
1325 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1326 ld_script = utils.installCygwinLDScript(ld_script_path)
1327 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1328 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1333 # fill in the version info
1334 env['VERSION_INFO'] = '''Configuration
1336 Special build flags: %s
1338 C Compiler flags: %s %s
1340 C++ Compiler LyX flags: %s
1341 C++ Compiler flags: %s %s
1343 Linker user flags: %s
1345 Builing directory: %s
1346 Local library directory: %s
1349 Frontend libraries: %s
1350 System libraries: %s
1351 include search path: %s
1357 ''' % (platform_name,
1358 env.subst('$CCFLAGS'), env.subst('$CC'),
1359 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1360 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1361 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1362 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1363 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1364 str(env['LIBPATH']), str(boost_libraries),
1365 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1366 frontend, packaging_method,
1367 prefix, env['LYX_DIR'])
1369 if frontend in ['qt2', 'qt3', 'qt4']:
1370 env['VERSION_INFO'] += ''' include dir: %s
1373 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1376 print env['VERSION_INFO']
1379 # Mingw command line may be too short for our link usage,
1380 # Here we use a trick from scons wiki
1381 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1383 # I also would like to add logging (commands only) capacity to the
1385 logfile = env.get('logfile', default_log_file)
1386 if logfile != '' or platform_name == 'win32':
1388 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1389 info = '''# This is a log of commands used by scons to build lyx
1393 ''' % (time.asctime(), ' '.join(sys.argv),
1394 env['VERSION_INFO'].replace('\n','\n# ')) )
1399 # -h will print out help info
1400 Help(opts.GenerateHelpText(env))
1402 # save environment settings (for fast_start option)
1403 cache_file = open(env_cache_file, 'w')
1404 cPickle.dump(env_cache, cache_file)
1408 #----------------------------------------------------------
1410 #----------------------------------------------------------
1411 # this has been the source of problems on some platforms...
1412 # I find that I need to supply it with full path name
1413 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1414 # this usage needs further investigation.
1415 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1417 print "Building all targets recursively"
1419 if env.has_key('rebuild'):
1420 rebuild_targets = env['rebuild'].split(',')
1422 rebuild_targets = None
1424 def libExists(libname):
1425 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1426 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1428 targets = BUILD_TARGETS
1429 # msvc need to pass full target name, so I have to look for path/lyx etc
1430 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1431 or 'install' in targets or 'all' in targets
1432 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1433 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1434 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1435 build_mathed = build_lyx or 'mathed' in targets
1436 build_insets = build_lyx or 'insets' in targets
1437 build_frontends = build_lyx or 'frontends' in targets
1438 build_graphics = build_lyx or 'graphics' in targets
1439 build_controllers = build_lyx or 'controllers' in targets
1440 build_client = True in ['client' in x for x in targets] \
1441 or 'install' in targets or 'all' in targets
1442 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1443 or 'install' in targets or 'all' in targets
1444 build_lyxbase = build_lyx or 'lyxbase' in targets
1445 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1446 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1447 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1448 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1449 build_msvs_projects = use_vc and 'msvs_projects' in targets
1452 # now, if rebuild_targets is specified, do not rebuild some targets
1453 rebuild_targets = rebuild_targets
1455 def ifBuildLib(name, libname, old_value):
1456 # explicitly asked to rebuild
1457 if name in rebuild_targets:
1459 # else if not rebuild, and if the library already exists
1460 elif libExists(libname):
1462 # do not change the original value
1465 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1466 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1467 build_support = ifBuildLib('support', 'support', build_support)
1468 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1469 build_insets = ifBuildLib('insets', 'insets', build_insets)
1470 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1471 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1472 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1473 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1474 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1475 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1476 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1478 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1492 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1494 boostenv = env.Copy()
1496 # boost use its own config.h
1497 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1498 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1500 for lib in boost_libs:
1501 print 'Processing files in boost/libs/%s/src...' % lib
1502 boostlib = boostenv.StaticLibrary(
1503 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1504 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1505 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1507 Alias('boost', boostlib)
1514 intlenv = env.Copy()
1516 print "Processing files in intl..."
1518 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1520 # we need the original C compiler for these files
1521 intlenv['CC'] = C_COMPILER
1522 intlenv['CCFLAGS'] = C_CCFLAGS
1524 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1525 # intl does not use global config.h
1526 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1528 intlenv.Append(CCFLAGS = [
1529 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1530 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1531 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1533 '-DENABLE_RELOCATABLE=1',
1535 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1537 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1538 '-Drelocate=libintl_relocate',
1539 '-DDEPENDS_ON_LIBICONV=1',
1544 intl = intlenv.StaticLibrary(
1545 target = '$LOCALLIBPATH/included_intl',
1547 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1548 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1549 build_dir = '$BUILDDIR/intl')
1555 # Now, src code under src/
1557 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1564 print "Processing files in src/support..."
1566 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1568 support = env.StaticLibrary(
1569 target = '$LOCALLIBPATH/support',
1570 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1571 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1572 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1574 Alias('support', support)
1581 print "Processing files in src/mathed..."
1583 mathed = env.StaticLibrary(
1584 target = '$LOCALLIBPATH/mathed',
1585 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1587 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1588 build_dir = '$BUILDDIR/common/mathed')
1590 Alias('mathed', mathed)
1597 print "Processing files in src/insets..."
1599 insets = env.StaticLibrary(
1600 target = '$LOCALLIBPATH/insets',
1601 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1603 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1605 Alias('insets', insets)
1612 print "Processing files in src/frontends..."
1614 frontends = env.StaticLibrary(
1615 target = '$LOCALLIBPATH/frontends',
1616 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1617 build_dir = '$BUILDDIR/common/frontends')
1619 Alias('frontends', frontends)
1626 print "Processing files in src/graphics..."
1628 graphics = env.StaticLibrary(
1629 target = '$LOCALLIBPATH/graphics',
1630 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1631 build_dir = '$BUILDDIR/common/graphics')
1633 Alias('graphics', graphics)
1636 if build_controllers:
1638 # src/frontends/controllers
1640 print "Processing files in src/frontends/controllers..."
1642 controllers = env.StaticLibrary(
1643 target = '$LOCALLIBPATH/controllers',
1644 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1645 build_dir = '$BUILDDIR/common/frontends/controllers')
1647 Alias('controllers', controllers)
1651 # src/frontend/qt2/3/4
1653 if build_qt2 or build_qt3 or build_qt4:
1654 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1658 print "Processing files in src/frontends/qt2..."
1661 # disable auto scan to speed up non build time
1662 qt2env['QT_AUTOSCAN'] = 0
1663 qt2env['QT_MOCHPREFIX'] = ''
1668 qt2env.AppendUnique(CPPPATH = [
1670 '$BUILDDIR/common/images',
1671 '$BUILDDIR/common/frontends',
1672 '$BUILDDIR/common/frontends/qt2',
1673 '$BUILDDIR/common/frontends/controllers',
1677 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1680 FileDialog_private.C
1719 QSpellcheckerDialog.C
1721 QTabularCreateDialog.C
1736 # manually moc and uic files for better performance
1737 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1739 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1740 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1742 qt2_uiced_cc_files = []
1743 for x in qt2_uiced_files:
1744 qt2_uiced_cc_files.extend(x[1:])
1746 qt2 = qt2env.StaticLibrary(
1747 target = '$LOCALLIBPATH/qt2',
1748 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1749 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1755 print "Processing files in src/frontends/qt3..."
1758 # disable auto scan to speed up non build time
1759 qt3env['QT_AUTOSCAN'] = 0
1760 qt3env['QT_MOCHPREFIX'] = ''
1765 qt3env.AppendUnique(CPPPATH = [
1767 '$BUILDDIR/common/images',
1768 '$BUILDDIR/common/frontends',
1769 '$BUILDDIR/common/frontends/qt3',
1770 '$BUILDDIR/common/frontends/controllers',
1774 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1777 FileDialog_private.C
1817 QSpellcheckerDialog.C
1819 QTabularCreateDialog.C
1834 # manually moc and uic files for better performance
1835 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1837 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1838 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1840 qt3_uiced_cc_files = []
1841 for x in qt3_uiced_files:
1842 qt3_uiced_cc_files.extend(x[1:])
1844 qt3 = qt3env.StaticLibrary(
1845 target = '$LOCALLIBPATH/qt3',
1846 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1847 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1853 print "Processing files in src/frontends/qt4..."
1856 qt4env['QT_AUTOSCAN'] = 0
1858 # local qt4 toolset from
1859 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1861 # NOTE: I have to patch qt4.py since it does not automatically
1862 # process .C file!!! (add to cxx_suffixes )
1864 qt4env.Tool('qt4', [scons_dir])
1865 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1867 qt4env.AppendUnique(CPPPATH = [
1869 '$BUILDDIR/common/images',
1870 '$BUILDDIR/common/frontends',
1871 '$BUILDDIR/common/frontends/qt4',
1872 '$BUILDDIR/common/frontends/controllers',
1877 # FIXME: replace by something from pkg_config
1878 qt4env.Append(CCFLAGS = [
1880 '-DQT_CLEAN_NAMESPACE',
1888 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1891 FileDialog_private.C
1934 QSpellcheckerDialog.C
1936 QTabularCreateDialog.C
1955 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1956 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1957 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1960 # moc qt4_moc_files, the moced files are included in the original files
1962 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1964 qt4 = qt4env.StaticLibrary(
1965 target = '$LOCALLIBPATH/qt4',
1966 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1967 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1976 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1978 print "Processing files in src/client..."
1980 if env['HAVE_FCNTL']:
1981 client = env.Program(
1982 target = '$BUILDDIR/common/client/lyxclient',
1983 LIBS = ['support'] + intl_libs + system_libs +
1984 socket_libs + boost_libraries,
1985 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1986 build_dir = '$BUILDDIR/common/client')
1988 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1989 client, [Copy('$TARGET', '$SOURCE')]))
1992 Alias('client', client)
1999 print "Processing files in src/tex2lyx..."
2001 tex2lyx_env = env.Copy()
2003 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2004 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2006 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2007 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2008 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2009 [Copy('$TARGET', '$SOURCE')])
2011 tex2lyx = tex2lyx_env.Program(
2012 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2013 LIBS = ['support'] + boost_libraries + system_libs,
2014 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2015 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2016 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2017 build_dir = '$BUILDDIR/common/tex2lyx')
2019 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2020 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2021 Alias('tex2lyx', tex2lyx)
2028 print "Processing files in src..."
2030 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2032 lyx_post_source = Split('''
2041 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2042 lyx_post_source.append('aspell.C')
2043 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2044 lyx_post_source.append('pspell.C')
2045 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2046 lyx_post_source.append('ispell.C')
2048 # msvc requires at least one source file with main()
2049 # so I exclude main.C from lyxbase
2050 lyxbase_pre = env.StaticLibrary(
2051 target = '$LOCALLIBPATH/lyxbase_pre',
2052 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2053 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2054 'ispell.C', 'Variables.C', 'Sectioning.C'],
2055 include = ['version.C'], build_dir = '$BUILDDIR/common')
2057 lyxbase_post = env.StaticLibrary(
2058 target = '$LOCALLIBPATH/lyxbase_post',
2059 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2061 Alias('lyxbase', lyxbase_pre)
2062 Alias('lyxbase', lyxbase_post)
2067 # Build lyx with given frontend
2070 target = '$BUILDDIR/$frontend/lyx',
2071 source = ['$BUILDDIR/common/main.C'],
2089 # [/path/to/lyx.ext] => lyx-qt3.ext
2090 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2091 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2092 [Copy('$TARGET', '$SOURCE')]))
2096 if build_msvs_projects:
2097 def build_project(target, dir, full_target = None,
2098 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2099 ''' build mavs project files
2100 target: alias (correspond to directory name)
2101 dir: source directory or directories (a list)
2102 full_target: full path/filename of the target
2103 src_pattern: glob pattern
2104 include: files to include into source
2105 resource: directory or directories with resource (.ui) files
2106 rebuildTargetOnly: whether or not only rebuild this target
2108 For non-debug-able targets like static libraries, target (alias) is
2109 enough to build the target. For executable targets, msvs need to know
2110 the full path to start debug them.
2112 if resource is not None:
2113 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2114 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2117 if rebuildTargetOnly:
2118 cmds = 'faststart=yes rebuild='+target
2120 cmds = 'faststart=yes'
2121 if type(dir) == type([]):
2125 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2126 pattern = src_pattern, include = include,
2127 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2128 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2130 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2132 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2133 pattern = src_pattern, include = include,
2134 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2135 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2137 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2138 if full_target is None:
2139 build_target = target
2141 build_target = full_target
2143 proj = env.MSVSProject(
2144 target = target + env['MSVSPROJECTSUFFIX'],
2146 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2149 buildtarget = build_target,
2153 Alias('msvs_projects', proj)
2155 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2156 src_pattern = '*.cpp')
2158 build_project('intl', 'intl', src_pattern = '*.c')
2160 build_project('support', 'src/support', include=['package.C.in'])
2162 build_project('mathed', 'src/mathed')
2164 build_project('insets', 'src/insets')
2166 build_project('frontends', 'src/frontends')
2168 build_project('graphics', 'src/graphics')
2170 build_project('controllers', 'src/frontends/controllers')
2172 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2174 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2176 build_project('client', 'src/client', rebuildTargetOnly = False,
2177 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2179 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2180 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2182 build_project('lyxbase', 'src')
2184 if frontend == 'qt3':
2185 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2186 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2187 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2188 rebuildTargetOnly = False,
2189 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2191 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2192 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2193 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2194 rebuildTargetOnly = False,
2195 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2202 print 'Processing files in po...'
2207 # files to translate
2208 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2209 # possibly *only* handle these languages
2211 if env.has_key('languages'):
2212 languages = env.make_list(env['lanauges'])
2213 # use defulat msgfmt
2214 if not env['MSGFMT']:
2215 print 'msgfmt does not exist. Can not process po files'
2218 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2221 for f in transfiles:
2223 fname = os.path.split(f)[1]
2225 country = fname.split('.')[0]
2227 if not languages or country in languages:
2228 gmo_files.extend(env.Transfiles(f))
2231 if 'install' in targets:
2233 # install to DESTDIR or prefix
2234 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2235 # if dest_dir is different from prefix.
2236 if env.has_key('exec_prefix'):
2237 bin_dest_dir = Dir(env['exec_prefix']).abspath
2239 bin_dest_dir = os.path.join(dest_dir, 'bin')
2241 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2243 share_dest_dir = os.path.join(dest_dir, share_dir)
2244 man_dest_dir = os.path.join(dest_dir, man_dir)
2245 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2246 # create the directory if needed
2247 if not os.path.isdir(dest_dir):
2249 os.makedirs(dest_dir)
2252 if not os.path.isdir(dest_dir):
2253 print 'Can not create directory', dest_dir
2258 # do not install these files
2259 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2260 'lyx2lyx_version.py.in']
2262 def install(dest, src):
2263 ''' recusive installation of src to dest '''
2264 # separate file and directory
2265 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2266 dirs = filter(os.path.isdir, src)
2268 env.Install(dest, files)
2272 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2273 glob.glob(os.path.join(dir, '*'))) )
2276 # executables (some of them may be none)
2279 version_suffix = program_suffix
2284 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2285 target = os.path.join(bin_dest_dir, target_name)
2286 env.InstallAs(target, lyx)
2287 Alias('install', target)
2288 # install lyx as lyx-qt3
2289 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2290 target = os.path.join(bin_dest_dir, target_name)
2291 env.InstallAs(target, lyx)
2292 Alias('install', target)
2295 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2296 target = os.path.join(bin_dest_dir, target_name)
2297 env.InstallAs(target, tex2lyx)
2298 Alias('install', target)
2300 # install lyxclient, may not exist
2302 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2303 target = os.path.join(bin_dest_dir, target_name)
2304 env.InstallAs(target, client)
2305 Alias('install', target)
2308 dirs = install(share_dest_dir,
2309 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2310 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2311 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2312 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2314 # lyx1.4.x does not have lyx2lyx_version.py.in
2315 if os.path.isfile('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in'):
2316 # subst and install this file
2317 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2318 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2319 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2320 Alias('install', dirs)
2322 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2323 env.subst('$TOP_SRCDIR/lyx.man'))
2324 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2325 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2326 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2327 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2328 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2329 x in ['lyx', 'tex2lyx', 'lyxclient']])
2331 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2332 for gmo in gmo_files:
2333 lan = os.path.split(str(gmo))[1].split('.')[0]
2334 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2335 env.InstallAs(dest_file, gmo)
2336 Alias('install', dest_file)
2340 Alias('all', ['lyx', 'client', 'tex2lyx'])