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 lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
705 inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
706 # default to $BUILDDIR/libs (use None since this path will be added anyway)
708 # here I assume that all libraries are in the same directory
709 if boost_opt == 'included':
710 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
711 included_boost = True
712 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
713 elif boost_opt == 'auto':
714 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, mode == 'debug')
715 # if not found, use local boost
717 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
718 included_boost = True
719 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
721 included_boost = False
722 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
723 elif boost_opt == 'system':
724 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, mode == 'debug')
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 included_boost = False
732 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
733 env_cache['BOOST_LIBRARIES'] = boost_libraries
734 env_cache['INCLUDED_BOOST'] = included_boost
735 env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
736 env_cache['BOOST_LIBPATH'] = boost_libpath
738 boost_libraries = env_cache['BOOST_LIBRARIES']
739 included_boost = env_cache['INCLUDED_BOOST']
740 env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
741 boost_libpath = env_cache['BOOST_LIBPATH']
743 if boost_libpath is not None:
744 env.AppendUnique(LIBPATH = [boost_libpath])
747 env['ENABLE_NLS'] = env['nls']
750 if not env['ENABLE_NLS']:
752 included_gettext = False
754 # check gettext libraries
755 gettext_opt = ARGUMENTS.get('gettext', 'auto')
756 # check for system gettext
758 if gettext_opt in ['auto', 'system']:
759 if conf.CheckLib('intl'):
760 included_gettext = False
764 if gettext_opt == 'system':
765 print "Can not find system gettext library"
766 print "Please supply a path through extra_lib_path and try again."
767 print "Or use gettext=included to use included gettext libraries."
769 # now, auto and succ = false, or gettext=included
771 # we do not need to set LIBPATH now.
772 included_gettext = True
773 intl_libs = ['included_intl']
774 env_cache['INCLUDED_GETTEXT'] = included_gettext
775 env_cache['INTL_LIBS'] = intl_libs
777 included_gettext = env_cache['INCLUDED_GETTEXT']
778 intl_libs = env_cache['INTL_LIBS']
781 # check for msgfmt command
783 env['MSGFMT'] = conf.CheckCommand('msgfmt')
784 env_cache['MSGFMT'] = env['MSGFMT']
786 env['MSGFMT'] = env_cache['MSGFMT']
788 # check uic and moc commands for qt frontends
790 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
791 or conf.CheckCommand('moc') == None):
792 print 'uic or moc command is not found for frontend', frontend
796 # Customized builders
798 # install customized builders
799 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
802 #----------------------------------------------------------
803 # Generating config.h
804 #----------------------------------------------------------
805 aspell_lib = 'aspell'
806 # assume that we use aspell, aspelld compiled for msvc
807 if platform_name == 'win32' and mode == 'debug' and use_vc:
808 aspell_lib = 'aspelld'
810 # check the existence of config.h
811 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
812 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
813 if not fast_start or not os.path.isfile(boost_config_h) \
814 or not os.path.isfile(config_h):
816 print "Creating %s..." % boost_config_h
818 utils.createConfigFile(conf,
819 config_file = boost_config_h,
820 config_pre = '''/* boost/config.h. Generated by SCons. */
825 * This file is part of LyX, the document processor.
826 * Licence details can be found in the file COPYING.
828 * This is the compilation configuration file for LyX.
829 * It was generated by scon.
830 * You might want to change some of the defaults if something goes wrong
831 * during the compilation.
834 #ifndef _BOOST_CONFIG_H
835 #define _BOOST_CONFIG_H
838 ('ostream', 'HAVE_OSTREAM', 'cxx'),
839 ('locale', 'HAVE_LOCALE', 'cxx'),
840 ('sstream', 'HAVE_SSTREAM', 'cxx'),
841 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
844 (env.has_key('assertions') and env['assertions'],
846 'Define if you want assertions to be enabled in the code'
851 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
852 # define USE_BOOST_FORMAT 1
854 # define USE_BOOST_FORMAT 0
857 #if !defined(ENABLE_ASSERTIONS)
858 # define BOOST_DISABLE_ASSERTS 1
860 #define BOOST_ENABLE_ASSERT_HANDLER 1
862 #define BOOST_DISABLE_THREADS 1
863 #define BOOST_NO_WREGEX 1
864 #define BOOST_NO_WSTRING 1
867 # define BOOST_POSIX 1
870 #define BOOST_ALL_NO_LIB 1
872 #if defined(HAVE_NEWAPIS_H)
873 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
880 print "\nGenerating %s..." % config_h
882 # AIKSAURUS_H_LOCATION
883 if (conf.CheckCXXHeader("Aiksaurus.h")):
884 aik_location = '<Aiksaurus.h>'
885 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
886 aik_location = '<Aiksaurus/Aiksaurus.h>'
890 # determine headers to use
891 spell_opt = ARGUMENTS.get('spell', 'auto')
892 env['USE_ASPELL'] = False
893 env['USE_PSPELL'] = False
894 env['USE_ISPELL'] = False
895 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
896 spell_engine = 'USE_ASPELL'
897 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
898 spell_engine = 'USE_PSPELL'
899 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
900 spell_engine = 'USE_ISPELL'
904 if spell_engine is not None:
905 env[spell_engine] = True
907 if spell_opt == 'auto':
908 print "Warning: Can not locate any spell checker"
909 elif spell_opt != 'no':
910 print "Warning: Can not locate specified spell checker:", spell_opt
913 # check arg types of select function
914 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
918 result = utils.createConfigFile(conf,
919 config_file = config_h,
920 config_pre = '''/* config.h. Generated by SCons. */
925 * This file is part of LyX, the document processor.
926 * Licence details can be found in the file COPYING.
928 * This is the compilation configuration file for LyX.
929 * It was generated by scon.
930 * You might want to change some of the defaults if something goes wrong
931 * during the compilation.
938 ('io.h', 'HAVE_IO_H', 'c'),
939 ('limits.h', 'HAVE_LIMITS_H', 'c'),
940 ('locale.h', 'HAVE_LOCALE_H', 'c'),
941 ('process.h', 'HAVE_PROCESS_H', 'c'),
942 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
943 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
944 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
945 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
946 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
947 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
948 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
949 ('utime.h', 'HAVE_UTIME_H', 'c'),
950 ('direct.h', 'HAVE_DIRECT_H', 'c'),
951 ('istream', 'HAVE_ISTREAM', 'cxx'),
952 ('ios', 'HAVE_IOS', 'cxx'),
955 ('open', 'HAVE_OPEN', None),
956 ('close', 'HAVE_CLOSE', None),
957 ('popen', 'HAVE_POPEN', None),
958 ('pclose', 'HAVE_PCLOSE', None),
959 ('_open', 'HAVE__OPEN', None),
960 ('_close', 'HAVE__CLOSE', None),
961 ('_popen', 'HAVE__POPEN', None),
962 ('_pclose', 'HAVE__PCLOSE', None),
963 ('getpid', 'HAVE_GETPID', None),
964 ('_getpid', 'HAVE__GETPID', None),
965 ('mkdir', 'HAVE_MKDIR', None),
966 ('_mkdir', 'HAVE__MKDIR', None),
967 ('mktemp', 'HAVE_MKTEMP', None),
968 ('mkstemp', 'HAVE_MKSTEMP', None),
969 ('strerror', 'HAVE_STRERROR', None),
970 ('count', 'HAVE_STD_COUNT', '''
975 return std::count(a, a+5, 'l');
978 ('getcwd', 'HAVE_GETCWD', None),
979 ('setenv', 'HAVE_SETENV', None),
980 ('putenv', 'HAVE_PUTENV', None),
981 ('fcntl', 'HAVE_FCNTL', None),
984 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
985 '#include <streambuf>\n#include <istream>')
988 ('gdi32', 'HAVE_LIBGDI32'),
989 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
990 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
993 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
995 'Define is sys/types.h does not have pid_t',
999 (conf.CheckCXXGlobalCstd(),
1001 'Define if your C++ compiler puts C library functions in the global namespace'
1003 (conf.CheckMkdirOneArg(),
1004 'MKDIR_TAKES_ONE_ARG',
1005 'Define if mkdir takes only one argument.'
1007 (conf.CheckLC_MESSAGES(),
1009 'Define if your <locale.h> file defines LC_MESSAGES.'
1011 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1014 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1016 (env['nls'] and not included_gettext,
1018 'Define to 1 if using system gettext library'
1020 (env.has_key('warnings') and env['warnings'],
1022 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1024 (env.has_key('concept_checks') and env['concept_checks'],
1025 '_GLIBCXX_CONCEPT_CHECKS',
1026 'libstdc++ concept checking'
1028 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1030 'libstdc++ debug mode'
1032 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1033 '_GLIBCXX_DEBUG_PEDANTIC',
1034 'libstdc++ pedantic debug mode'
1036 (os.name != 'nt', 'BOOST_POSIX',
1037 'Indicates to boost which API to use (posix or windows).'
1039 (spell_engine is not None, spell_engine,
1040 'Spell engine to use'
1044 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1046 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1047 'Define to the address where bug reports for this package should be sent.'),
1048 ('#define PACKAGE_NAME "%s"' % package_name,
1049 'Define to the full name of this package.'),
1050 ('#define PACKAGE_STRING "%s"' % package_string,
1051 'Define to the full name and version of this package.'),
1052 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1053 'Define to the one symbol short name of this package.'),
1054 ('#define PACKAGE_VERSION "%s"' % package_version,
1055 'Define to the version of this package.'),
1056 ('#define BOOST_ALL_NO_LIB 1',
1057 'disable automatic linking of boost libraries.'),
1058 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1059 'Packaging method'),
1060 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1061 'Aiksaurus include file'),
1062 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1063 "Define to the type of arg 1 for `select'."),
1064 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1065 "Define to the type of arg 2, 3, 4 for `select'."),
1066 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1067 "Define to the type of arg 5 for `select'."),
1069 config_post = '''/************************************************************
1070 ** You should not need to change anything beyond this point */
1072 #ifndef HAVE_STRERROR
1073 #if defined(__cplusplus)
1076 char * strerror(int n);
1080 #ifndef HAVE_DECL_MKSTEMP
1081 #if defined(__cplusplus)
1088 #include <../boost/config.h>
1094 # these keys are needed in env
1095 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1096 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1097 'ICONV_LIB', 'AIKSAURUS_LIB']:
1098 # USE_ASPELL etc does not go through result
1099 if result.has_key(key):
1100 env[key] = result[key]
1101 env_cache[key] = env[key]
1104 # if nls=yes and gettext=included, create intl/config.h
1105 # intl/libintl.h etc
1107 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1108 if env['nls'] and included_gettext:
1110 print "Creating %s..." % intl_config_h
1112 # create intl/config.h
1113 result = utils.createConfigFile(conf,
1114 config_file = intl_config_h,
1115 config_pre = '''/* intl/config.h. Generated by SCons. */
1120 * This file is part of LyX, the document processor.
1121 * Licence details can be found in the file COPYING.
1123 * This is the compilation configuration file for LyX.
1124 * It was generated by scon.
1125 * You might want to change some of the defaults if something goes wrong
1126 * during the compilation.
1133 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1134 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1135 ('string.h', 'HAVE_STRING_H', 'c'),
1136 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1137 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1138 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1139 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1140 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1141 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1142 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1145 ('getcwd', 'HAVE_GETCWD', None),
1146 ('stpcpy', 'HAVE_STPCPY', None),
1147 ('strcasecmp', 'HAVE_STRCASECMP', None),
1148 ('strdup', 'HAVE_STRDUP', None),
1149 ('strtoul', 'HAVE_STRTOUL', None),
1150 ('alloca', 'HAVE_ALLOCA', None),
1151 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1152 ('mempcpy', 'HAVE_MEMPCPY', None),
1153 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1154 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1155 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1156 ('setlocale', 'HAVE_SETLOCALE', None),
1157 ('tsearch', 'HAVE_TSEARCH', None),
1158 ('getegid', 'HAVE_GETEGID', None),
1159 ('getgid', 'HAVE_GETGID', None),
1160 ('getuid', 'HAVE_GETUID', None),
1161 ('wcslen', 'HAVE_WCSLEN', None),
1162 ('asprintf', 'HAVE_ASPRINTF', None),
1163 ('wprintf', 'HAVE_WPRINTF', None),
1164 ('snprintf', 'HAVE_SNPRINTF', None),
1165 ('printf', 'HAVE_POSIX_PRINTF', None),
1166 ('fcntl', 'HAVE_FCNTL', None),
1169 ('intmax_t', 'HAVE_INTMAX_T', None),
1170 ('long double', 'HAVE_LONG_DOUBLE', None),
1171 ('long long', 'HAVE_LONG_LONG', None),
1172 ('wchar_t', 'HAVE_WCHAR_T', None),
1173 ('wint_t', 'HAVE_WINT_T', None),
1174 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1175 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1178 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1182 (conf.CheckLC_MESSAGES(),
1184 'Define if your <locale.h> file defines LC_MESSAGES.'
1186 (conf.CheckIconvConst(),
1188 'Define as const if the declaration of iconv() needs const.',
1189 '#define ICONV_CONST',
1190 '#define ICONV_CONST const',
1192 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1193 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1195 "Define to 1 if you have the `intmax_t' type."
1197 (env.has_key('nls') and env['nls'],
1199 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1202 config_post = '#endif'
1205 # these keys are needed in env
1206 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1207 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1208 # USE_ASPELL etc does not go through result
1209 if result.has_key(key):
1210 env[key] = result[key]
1211 env_cache[key] = env[key]
1215 # this comes as a big surprise, without this line
1216 # (doing nothing obvious), adding fast_start=yes
1217 # to a build with fast_start=no will result in a rebuild
1218 # Note that the exact header file to check does not matter
1219 conf.CheckCHeader('io.h')
1220 # only a few variables need to be rescanned
1221 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1222 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1223 'ICONV_LIB', 'AIKSAURUS_LIB']:
1224 env[key] = env_cache[key]
1227 if env['nls'] and included_gettext:
1228 # only a few variables need to be rescanned
1229 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1230 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1231 env[key] = env_cache[key]
1233 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1234 if env['nls'] and included_gettext:
1235 # libgnuintl.h.in => libintl.h
1236 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1237 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1238 [Copy('$TARGET', '$SOURCE')])
1241 # Finish auto-configuration
1244 #----------------------------------------------------------
1245 # Now set up our build process accordingly
1246 #----------------------------------------------------------
1251 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1252 # in their respective directory and specialized env.
1253 if frontend in ['qt2', 'qt3']:
1254 # note: env.Tool('qt') my set QT_LIB to qt
1256 frontend_libs = ['qt-mt']
1257 elif frontend == 'qt4':
1258 qt_libs = ['QtCore', 'QtGui']
1259 # set the right lib names
1260 if platform_name == 'win32':
1261 if mode == 'debug' and use_vc:
1262 qt_lib_suffix = 'd4'
1267 qt_lib_suffix = '_debug'
1270 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1273 if platform_name in ['win32', 'cygwin']:
1274 # the final link step needs stdc++ to succeed under mingw
1275 # FIXME: shouldn't g++ automatically link to stdc++?
1277 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1279 system_libs = ['shlwapi', 'stdc++', 'z']
1280 elif platform_name == 'cygwin' and env['X11']:
1281 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1282 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1288 ('HAVE_ICONV', env['ICONV_LIB']),
1289 ('HAVE_LIBGDI32', 'gdi32'),
1290 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1291 ('USE_ASPELL', aspell_lib),
1292 ('USE_ISPELL', 'ispell'),
1293 ('USE_PSPELL', 'pspell'),
1298 system_libs.append(lib[1])
1301 # Build parameters CPPPATH etc
1304 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1307 # boost: for boost header files
1308 # BUILDDIR/common: for config.h
1309 # TOP_SRCDIR/src: for support/* etc
1311 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1313 # Separating boost directories from CPPPATH stops scons from building
1314 # the dependency tree of boost header files, and effectively reduce
1315 # the null build time of lyx from 29s to 16s.
1317 env.AppendUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1319 env.AppendUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1321 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1322 if env['nls'] and included_gettext:
1323 env['CPPPATH'].append('$BUILDDIR/intl')
1325 # QT_INC_PATH is not needed for *every* source file
1326 env['CPPPATH'].remove(qt_inc_path)
1329 # A Link script for cygwin see
1330 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1331 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1334 if platform_name == 'cygwin':
1335 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1336 ld_script = utils.installCygwinLDScript(ld_script_path)
1337 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1338 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1343 # fill in the version info
1344 env['VERSION_INFO'] = '''Configuration
1346 Special build flags: %s
1348 C Compiler flags: %s %s
1350 C++ Compiler LyX flags: %s
1351 C++ Compiler flags: %s %s
1353 Linker user flags: %s
1355 Builing directory: %s
1356 Local library directory: %s
1359 Frontend libraries: %s
1360 System libraries: %s
1361 include search path: %s
1367 ''' % (platform_name,
1368 env.subst('$CCFLAGS'), env.subst('$CC'),
1369 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1370 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1371 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1372 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1373 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1374 str(env['LIBPATH']), str(boost_libraries),
1375 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1376 frontend, packaging_method,
1377 prefix, env['LYX_DIR'])
1379 if frontend in ['qt2', 'qt3', 'qt4']:
1380 env['VERSION_INFO'] += ''' include dir: %s
1383 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1386 print env['VERSION_INFO']
1389 # Mingw command line may be too short for our link usage,
1390 # Here we use a trick from scons wiki
1391 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1393 # I also would like to add logging (commands only) capacity to the
1395 logfile = env.get('logfile', default_log_file)
1396 if logfile != '' or platform_name == 'win32':
1398 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1399 info = '''# This is a log of commands used by scons to build lyx
1403 ''' % (time.asctime(), ' '.join(sys.argv),
1404 env['VERSION_INFO'].replace('\n','\n# ')) )
1409 # -h will print out help info
1410 Help(opts.GenerateHelpText(env))
1412 # save environment settings (for fast_start option)
1413 cache_file = open(env_cache_file, 'w')
1414 cPickle.dump(env_cache, cache_file)
1418 #----------------------------------------------------------
1420 #----------------------------------------------------------
1421 # this has been the source of problems on some platforms...
1422 # I find that I need to supply it with full path name
1423 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1424 # this usage needs further investigation.
1425 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1427 print "Building all targets recursively"
1429 if env.has_key('rebuild'):
1430 rebuild_targets = env['rebuild'].split(',')
1432 rebuild_targets = None
1434 def libExists(libname):
1435 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1436 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1438 targets = BUILD_TARGETS
1439 # msvc need to pass full target name, so I have to look for path/lyx etc
1440 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1441 or 'install' in targets or 'all' in targets
1442 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1443 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1444 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1445 build_mathed = build_lyx or 'mathed' in targets
1446 build_insets = build_lyx or 'insets' in targets
1447 build_frontends = build_lyx or 'frontends' in targets
1448 build_graphics = build_lyx or 'graphics' in targets
1449 build_controllers = build_lyx or 'controllers' in targets
1450 build_client = True in ['client' in x for x in targets] \
1451 or 'install' in targets or 'all' in targets
1452 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1453 or 'install' in targets or 'all' in targets
1454 build_lyxbase = build_lyx or 'lyxbase' in targets
1455 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1456 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1457 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1458 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1459 build_msvs_projects = use_vc and 'msvs_projects' in targets
1462 # now, if rebuild_targets is specified, do not rebuild some targets
1463 rebuild_targets = rebuild_targets
1465 def ifBuildLib(name, libname, old_value):
1466 # explicitly asked to rebuild
1467 if name in rebuild_targets:
1469 # else if not rebuild, and if the library already exists
1470 elif libExists(libname):
1472 # do not change the original value
1475 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1476 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1477 build_support = ifBuildLib('support', 'support', build_support)
1478 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1479 build_insets = ifBuildLib('insets', 'insets', build_insets)
1480 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1481 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1482 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1483 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1484 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1485 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1486 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1488 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1502 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1504 boostenv = env.Copy()
1506 # boost use its own config.h
1507 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1508 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1510 for lib in boost_libs:
1511 print 'Processing files in boost/libs/%s/src...' % lib
1512 boostlib = boostenv.StaticLibrary(
1513 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1514 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1515 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1517 Alias('boost', boostlib)
1524 intlenv = env.Copy()
1526 print "Processing files in intl..."
1528 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1530 # we need the original C compiler for these files
1531 intlenv['CC'] = C_COMPILER
1532 intlenv['CCFLAGS'] = C_CCFLAGS
1534 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1535 # intl does not use global config.h
1536 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1538 intlenv.Append(CCFLAGS = [
1539 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1540 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1541 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1543 '-DENABLE_RELOCATABLE=1',
1545 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1547 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1548 '-Drelocate=libintl_relocate',
1549 '-DDEPENDS_ON_LIBICONV=1',
1554 intl = intlenv.StaticLibrary(
1555 target = '$LOCALLIBPATH/included_intl',
1557 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1558 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1559 build_dir = '$BUILDDIR/intl')
1565 # Now, src code under src/
1567 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1574 print "Processing files in src/support..."
1576 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1578 support = env.StaticLibrary(
1579 target = '$LOCALLIBPATH/support',
1580 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1581 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1582 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1584 Alias('support', support)
1591 print "Processing files in src/mathed..."
1593 mathed = env.StaticLibrary(
1594 target = '$LOCALLIBPATH/mathed',
1595 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1597 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1598 build_dir = '$BUILDDIR/common/mathed')
1600 Alias('mathed', mathed)
1607 print "Processing files in src/insets..."
1609 insets = env.StaticLibrary(
1610 target = '$LOCALLIBPATH/insets',
1611 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1613 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1615 Alias('insets', insets)
1622 print "Processing files in src/frontends..."
1624 frontends = env.StaticLibrary(
1625 target = '$LOCALLIBPATH/frontends',
1626 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1627 build_dir = '$BUILDDIR/common/frontends')
1629 Alias('frontends', frontends)
1636 print "Processing files in src/graphics..."
1638 graphics = env.StaticLibrary(
1639 target = '$LOCALLIBPATH/graphics',
1640 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1641 build_dir = '$BUILDDIR/common/graphics')
1643 Alias('graphics', graphics)
1646 if build_controllers:
1648 # src/frontends/controllers
1650 print "Processing files in src/frontends/controllers..."
1652 controllers = env.StaticLibrary(
1653 target = '$LOCALLIBPATH/controllers',
1654 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1655 build_dir = '$BUILDDIR/common/frontends/controllers')
1657 Alias('controllers', controllers)
1661 # src/frontend/qt2/3/4
1663 if build_qt2 or build_qt3 or build_qt4:
1664 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1668 print "Processing files in src/frontends/qt2..."
1671 # disable auto scan to speed up non build time
1672 qt2env['QT_AUTOSCAN'] = 0
1673 qt2env['QT_MOCHPREFIX'] = ''
1678 qt2env.AppendUnique(CPPPATH = [
1680 '$BUILDDIR/common/images',
1681 '$BUILDDIR/common/frontends',
1682 '$BUILDDIR/common/frontends/qt2',
1683 '$BUILDDIR/common/frontends/controllers',
1687 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1690 FileDialog_private.C
1729 QSpellcheckerDialog.C
1731 QTabularCreateDialog.C
1746 # manually moc and uic files for better performance
1747 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1749 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1750 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1752 qt2_uiced_cc_files = []
1753 for x in qt2_uiced_files:
1754 qt2_uiced_cc_files.extend(x[1:])
1756 qt2 = qt2env.StaticLibrary(
1757 target = '$LOCALLIBPATH/qt2',
1758 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1759 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1765 print "Processing files in src/frontends/qt3..."
1768 # disable auto scan to speed up non build time
1769 qt3env['QT_AUTOSCAN'] = 0
1770 qt3env['QT_MOCHPREFIX'] = ''
1775 qt3env.AppendUnique(CPPPATH = [
1777 '$BUILDDIR/common/images',
1778 '$BUILDDIR/common/frontends',
1779 '$BUILDDIR/common/frontends/qt3',
1780 '$BUILDDIR/common/frontends/controllers',
1784 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1787 FileDialog_private.C
1827 QSpellcheckerDialog.C
1829 QTabularCreateDialog.C
1844 # manually moc and uic files for better performance
1845 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1847 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1848 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1850 qt3_uiced_cc_files = []
1851 for x in qt3_uiced_files:
1852 qt3_uiced_cc_files.extend(x[1:])
1854 qt3 = qt3env.StaticLibrary(
1855 target = '$LOCALLIBPATH/qt3',
1856 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1857 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1863 print "Processing files in src/frontends/qt4..."
1866 qt4env['QT_AUTOSCAN'] = 0
1868 # local qt4 toolset from
1869 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1871 # NOTE: I have to patch qt4.py since it does not automatically
1872 # process .C file!!! (add to cxx_suffixes )
1874 qt4env.Tool('qt4', [scons_dir])
1875 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1877 qt4env.AppendUnique(CPPPATH = [
1879 '$BUILDDIR/common/images',
1880 '$BUILDDIR/common/frontends',
1881 '$BUILDDIR/common/frontends/qt4',
1882 '$BUILDDIR/common/frontends/controllers',
1887 # FIXME: replace by something from pkg_config
1888 qt4env.Append(CCFLAGS = [
1890 '-DQT_CLEAN_NAMESPACE',
1898 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1901 FileDialog_private.C
1944 QSpellcheckerDialog.C
1946 QTabularCreateDialog.C
1965 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1966 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1967 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1970 # moc qt4_moc_files, the moced files are included in the original files
1972 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1974 qt4 = qt4env.StaticLibrary(
1975 target = '$LOCALLIBPATH/qt4',
1976 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1977 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1986 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1988 print "Processing files in src/client..."
1990 if env['HAVE_FCNTL']:
1991 client = env.Program(
1992 target = '$BUILDDIR/common/client/lyxclient',
1993 LIBS = ['support'] + intl_libs + system_libs +
1994 socket_libs + boost_libraries,
1995 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1996 build_dir = '$BUILDDIR/common/client')
1998 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1999 client, [Copy('$TARGET', '$SOURCE')]))
2002 Alias('client', client)
2009 print "Processing files in src/tex2lyx..."
2011 tex2lyx_env = env.Copy()
2013 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2014 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2016 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2017 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2018 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2019 [Copy('$TARGET', '$SOURCE')])
2021 tex2lyx = tex2lyx_env.Program(
2022 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2023 LIBS = ['support'] + boost_libraries + system_libs,
2024 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2025 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2026 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2027 build_dir = '$BUILDDIR/common/tex2lyx')
2029 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2030 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2031 Alias('tex2lyx', tex2lyx)
2038 print "Processing files in src..."
2040 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2042 lyx_post_source = Split('''
2051 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2052 lyx_post_source.append('aspell.C')
2053 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2054 lyx_post_source.append('pspell.C')
2055 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2056 lyx_post_source.append('ispell.C')
2058 # msvc requires at least one source file with main()
2059 # so I exclude main.C from lyxbase
2060 lyxbase_pre = env.StaticLibrary(
2061 target = '$LOCALLIBPATH/lyxbase_pre',
2062 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2063 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2064 'ispell.C', 'Variables.C', 'Sectioning.C'],
2065 include = ['version.C'], build_dir = '$BUILDDIR/common')
2067 lyxbase_post = env.StaticLibrary(
2068 target = '$LOCALLIBPATH/lyxbase_post',
2069 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2071 Alias('lyxbase', lyxbase_pre)
2072 Alias('lyxbase', lyxbase_post)
2077 # Build lyx with given frontend
2080 target = '$BUILDDIR/$frontend/lyx',
2081 source = ['$BUILDDIR/common/main.C'],
2099 # [/path/to/lyx.ext] => lyx-qt3.ext
2100 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2101 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2102 [Copy('$TARGET', '$SOURCE')]))
2106 if build_msvs_projects:
2107 def build_project(target, dir, full_target = None,
2108 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2109 ''' build mavs project files
2110 target: alias (correspond to directory name)
2111 dir: source directory or directories (a list)
2112 full_target: full path/filename of the target
2113 src_pattern: glob pattern
2114 include: files to include into source
2115 resource: directory or directories with resource (.ui) files
2116 rebuildTargetOnly: whether or not only rebuild this target
2118 For non-debug-able targets like static libraries, target (alias) is
2119 enough to build the target. For executable targets, msvs need to know
2120 the full path to start debug them.
2122 if resource is not None:
2123 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2124 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2127 if rebuildTargetOnly:
2128 cmds = 'faststart=yes rebuild='+target
2130 cmds = 'faststart=yes'
2131 if type(dir) == type([]):
2135 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2136 pattern = src_pattern, include = include,
2137 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2138 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2140 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2142 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2143 pattern = src_pattern, include = include,
2144 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2145 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2147 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2148 if full_target is None:
2149 build_target = target
2151 build_target = full_target
2153 proj = env.MSVSProject(
2154 target = target + env['MSVSPROJECTSUFFIX'],
2156 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2159 buildtarget = build_target,
2163 Alias('msvs_projects', proj)
2165 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2166 src_pattern = '*.cpp')
2168 build_project('intl', 'intl', src_pattern = '*.c')
2170 build_project('support', 'src/support', include=['package.C.in'])
2172 build_project('mathed', 'src/mathed')
2174 build_project('insets', 'src/insets')
2176 build_project('frontends', 'src/frontends')
2178 build_project('graphics', 'src/graphics')
2180 build_project('controllers', 'src/frontends/controllers')
2182 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2184 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2186 build_project('client', 'src/client', rebuildTargetOnly = False,
2187 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2189 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2190 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2192 build_project('lyxbase', 'src')
2194 if frontend == 'qt3':
2195 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2196 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2197 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2198 rebuildTargetOnly = False,
2199 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2201 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2202 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2203 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2204 rebuildTargetOnly = False,
2205 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2212 print 'Processing files in po...'
2217 # files to translate
2218 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2219 # possibly *only* handle these languages
2221 if env.has_key('languages'):
2222 languages = env.make_list(env['lanauges'])
2223 # use defulat msgfmt
2224 if not env['MSGFMT']:
2225 print 'msgfmt does not exist. Can not process po files'
2228 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2231 for f in transfiles:
2233 fname = os.path.split(f)[1]
2235 country = fname.split('.')[0]
2237 if not languages or country in languages:
2238 gmo_files.extend(env.Transfiles(f))
2241 if 'install' in targets:
2243 # install to DESTDIR or prefix
2244 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2245 # if dest_dir is different from prefix.
2246 if env.has_key('exec_prefix'):
2247 bin_dest_dir = Dir(env['exec_prefix']).abspath
2249 bin_dest_dir = os.path.join(dest_dir, 'bin')
2251 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2253 share_dest_dir = os.path.join(dest_dir, share_dir)
2254 man_dest_dir = os.path.join(dest_dir, man_dir)
2255 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2256 # create the directory if needed
2257 if not os.path.isdir(dest_dir):
2259 os.makedirs(dest_dir)
2262 if not os.path.isdir(dest_dir):
2263 print 'Can not create directory', dest_dir
2268 # do not install these files
2269 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2270 'lyx2lyx_version.py.in']
2272 def install(dest, src):
2273 ''' recusive installation of src to dest '''
2274 # separate file and directory
2275 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2276 dirs = filter(os.path.isdir, src)
2278 env.Install(dest, files)
2282 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2283 glob.glob(os.path.join(dir, '*'))) )
2286 # executables (some of them may be none)
2289 version_suffix = program_suffix
2294 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2295 target = os.path.join(bin_dest_dir, target_name)
2296 env.InstallAs(target, lyx)
2297 Alias('install', target)
2298 # install lyx as lyx-qt3
2299 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2300 target = os.path.join(bin_dest_dir, target_name)
2301 env.InstallAs(target, lyx)
2302 Alias('install', target)
2305 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2306 target = os.path.join(bin_dest_dir, target_name)
2307 env.InstallAs(target, tex2lyx)
2308 Alias('install', target)
2310 # install lyxclient, may not exist
2312 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2313 target = os.path.join(bin_dest_dir, target_name)
2314 env.InstallAs(target, client)
2315 Alias('install', target)
2318 dirs = install(share_dest_dir,
2319 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2320 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2321 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2322 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2324 # lyx1.4.x does not have lyx2lyx_version.py.in
2325 if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2326 # subst and install this file
2327 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2328 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2329 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2330 Alias('install', dirs)
2332 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2333 env.subst('$TOP_SRCDIR/lyx.man'))
2334 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2335 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2336 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2337 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2338 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2339 x in ['lyx', 'tex2lyx', 'lyxclient']])
2341 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2342 for gmo in gmo_files:
2343 lan = os.path.split(str(gmo))[1].split('.')[0]
2344 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2345 env.InstallAs(dest_file, gmo)
2346 Alias('install', dest_file)
2350 Alias('all', ['lyx', 'client', 'tex2lyx'])