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'
107 #---------------------------------------------------------
109 #----------------------------------------------------------
111 # You can set perminant default values in config.py
112 if os.path.isfile('config.py'):
113 print "Getting options from config.py..."
114 print open('config.py').read()
116 opts = Options(['config.py'])
119 EnumOption('frontend', 'Main GUI', default_frontend,
120 allowed_values = ('xform', 'qt2', 'qt3', 'qt4', 'gtk') ),
121 # debug or release build
122 EnumOption('mode', 'Building method', default_build_mode,
123 allowed_values = ('debug', 'release') ),
126 'Use included, system boost library, or try sytem boost first.',
127 'auto', allowed_values = (
128 'auto', # detect boost, if not found, use included
129 'included', # always use included boost
130 'system', # always use system boost, fail if can not find
133 EnumOption('gettext',
134 'Use included, system gettext library, or try sytem gettext first',
135 'auto', allowed_values = (
136 'auto', # detect gettext, if not found, use included
137 'included', # always use included gettext
138 'system', # always use system gettext, fail if can not find
141 EnumOption('spell', 'Choose spell checker to use.', 'auto',
142 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
144 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
145 allowed_values = ('windows', 'posix', 'macosx')),
147 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
148 # No precompiled header support (too troublesome to make it work for msvc)
149 # BoolOption('pch', 'Whether or not use pch', False),
150 # enable assertion, (config.h has ENABLE_ASSERTIOS
151 BoolOption('assertions', 'Use assertions', True),
152 # enable warning, (config.h has WITH_WARNINGS)
153 # default to False since MSVC does not have #warning
154 BoolOption('warnings', 'Use warnings', False),
155 # config.h define _GLIBCXX_CONCEPT_CHECKS
156 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
157 BoolOption('concept_checks', 'Enable concept checks', True),
159 BoolOption('nls', 'Whether or not use native language support', True),
161 BoolOption('profiling', 'Whether or not enable profiling', False),
162 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
163 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
165 BoolOption('X11', 'Use x11 windows system', default_with_x),
166 # use MS VC++ to build lyx
167 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
169 PathOption('qt_dir', 'Path to qt directory', None),
171 PathOption('qt_include_path', 'Path to qt include directory', None),
173 PathOption('qt_lib_path', 'Path to qt library directory', None),
174 # build directory, will use $mode if not set
175 PathOption('build_dir', 'Build directory', None),
176 # extra include and libpath
177 PathOption('extra_inc_path', 'Extra include path', None),
179 PathOption('extra_lib_path', 'Extra library path', None),
181 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
183 PathOption('extra_inc_path1', 'Extra include path', None),
185 PathOption('extra_lib_path1', 'Extra library path', None),
186 # rebuild only specifed, comma separated targets
187 ('rebuild', 'rebuild only specifed, comma separated targets', None),
188 # can be set to a non-existing directory
189 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
191 ('version_suffix', 'install lyx as lyx-suffix', None),
192 # how to load options
193 ('load_option', '''load option from previous scons run. option can be
194 yes (default): load all options
195 no: do not load any option
196 opt1,opt2: load specified options
197 -opt1,opt2: load all options other than specified ones''', 'yes'),
199 ('optimization', 'optimization CCFLAGS option.', None),
201 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
203 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
204 # provided for backward compatibility
205 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
206 # environment variable can be set as options.
207 ('DESTDIR', 'install to DESTDIR', None),
208 ('CC', 'replace default $CC', None),
209 ('LINK', 'replace default $LINK', None),
210 ('CPP', 'replace default $CPP', None),
211 ('CXX', 'replace default $CXX', None),
212 ('CXXCPP', 'replace default $CXXCPP', None),
213 ('CCFLAGS', 'replace default $CCFLAGS', None),
214 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
215 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
218 # copied from SCons/Options/BoolOption.py
219 # We need to use them before a boolean ARGUMENTS option is available
221 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
222 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
224 # whether or not use current config.h, and cached tests
226 # if fast_start=yes (default), load variables from env_cache_file
227 if (not ARGUMENTS.has_key('fast_start') or \
228 ARGUMENTS['fast_start'] in true_strings) \
229 and os.path.isfile(env_cache_file):
231 cache_file = open(env_cache_file)
232 env_cache = cPickle.load(cache_file)
234 print '------------ fast_start mode --------------------'
235 print ' Use cached test results and current config.h'
236 print ' use fast_start=no to override'
242 # if load_option=yes (default), load saved comand line options
244 # This option can take value yes/no/opt1,opt2/-opt1,opt2
245 # and tries to be clever in choosing options to load
246 if (not ARGUMENTS.has_key('load_option') or \
247 ARGUMENTS['load_option'] not in false_strings) \
248 and os.path.isfile(env_cache_file):
249 cache_file = open(env_cache_file)
250 opt_cache = cPickle.load(cache_file)['arg_cache']
252 # import cached options, but we should ignore qt_dir when frontend changes
253 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
254 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
255 and opt_cache.has_key('qt_dir'):
256 opt_cache.pop('qt_dir')
257 # some options will require full rebuild
258 # these are in general things that will change config.h
259 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
260 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
261 ARGUMENTS[arg] != opt_cache[arg]):
263 print " ** fast_start is disabled because of the change of option", arg
266 # and we do not cache some options
267 for arg in ['fast_start', 'load_option']:
268 if opt_cache.has_key(arg):
270 # now, if load_option=opt1,opt2 or -opt1,opt2
271 if ARGUMENTS.has_key('load_option') and \
272 ARGUMENTS['load_option'] not in true_strings + false_strings:
273 # if -opt1,opt2 is specified, do not load these options
274 if ARGUMENTS['load_option'][0] == '-':
275 for arg in ARGUMENTS['load_option'][1:].split(','):
276 if opt_cache.has_key(arg):
278 # if opt1,opt2 is specified, only load specified options
280 args = ARGUMENTS['load_option'].split(',')
281 for arg in opt_cache.keys():
284 # now restore options as if entered from command line
285 for key in opt_cache.keys():
286 if not ARGUMENTS.has_key(key):
287 ARGUMENTS[key] = opt_cache[key]
288 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
292 env_cache['arg_cache'] = ARGUMENTS
295 #---------------------------------------------------------
296 # Setting up environment
297 #---------------------------------------------------------
299 # I do not really like ENV=os.environ, but you may add it
300 # here if you experience some environment related problem
301 env = Environment(options = opts)
303 # set individual variables since I do not really like ENV = os.environ
304 env['ENV']['PATH'] = os.environ.get('PATH')
305 env['ENV']['HOME'] = os.environ.get('HOME')
306 # these are defined for MSVC
307 env['ENV']['LIB'] = os.environ.get('LIB')
308 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
310 # for simplicity, use var instead of env[var]
311 frontend = env['frontend']
312 prefix = env['prefix']
315 if platform_name == 'win32':
316 if env.has_key('use_vc'):
317 use_vc = env['use_vc']
318 if WhereIs('cl.exe') is None:
319 print "cl.exe is not found. Are you using the MSVC environment?"
321 elif WhereIs('cl.exe') is not None:
328 # lyx will be built to $build/build_dir so it is possible
329 # to build multiple build_dirs using the same source
330 # $mode can be debug or release
331 if env.has_key('build_dir') and env['build_dir'] is not None:
332 env['BUILDDIR'] = env['build_dir']
334 # Determine the name of the build $mode
335 env['BUILDDIR'] = '#' + mode
337 # all built libraries will go to build_dir/libs
338 # (This is different from the make file approach)
339 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
340 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
343 # Here is a summary of variables defined in env
345 # 2. undefined options with a non-None default value
346 # 3. compiler commands and flags like CCFLAGS.
347 # MSGFMT used to process po files
348 # 4. Variables that will be used to replace variables in some_file.in
349 # src/support/package.C.in:
350 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
351 # lib/lyx2lyx/lyx2lyx_version.py.in
354 # PACKAGE_VERSION, VERSION_INFO
355 # src/frontends/xforms/lyx_xpm.h.in
357 # src/frontends/xforms/lyx_forms.h.in
360 # full path name is used to build msvs project files
361 # and to replace TOP_SRCDIR in package.C
362 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
363 # needed by src/version.C.in => src/version.C
364 env['PACKAGE_VERSION'] = package_version
366 # determine share_dir etc
367 packaging_method = env.get('packaging')
368 if packaging_method == 'windows':
369 share_dir = 'Resources'
370 man_dir = 'Resources/man/man1'
371 locale_dir = 'Resources/locale'
372 default_prefix = 'c:/program files/lyx'
374 share_dir = 'share/lyx'
376 locale_dir = 'share/locale'
377 default_prefix = '/usr/local/'
379 # install to default_prefix by default
380 # program suffix: can be yes, or a string
381 if env.has_key('version_suffix'):
382 if env['version_suffix'] in true_strings:
383 program_suffix = package_version
384 elif env['version_suffix'] in false_strings:
387 program_suffix = env['version_suffix']
390 # used by package.C.in
391 env['PROGRAM_SUFFIX'] = program_suffix
393 # whether or not add suffix to file and directory names
394 add_suffix = packaging_method != 'windows'
395 # LYX_DIR are different (used in package.C.in)
397 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
399 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
400 # we need absolute path for package.C
401 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
404 #---------------------------------------------------------
405 # Setting building environment (Tools, compiler flags etc)
406 #---------------------------------------------------------
408 # Since Tool('mingw') will reset CCFLAGS etc, this should be
409 # done before getEnvVariable
410 if platform_name == 'win32':
416 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
418 # we differentiate between hard-coded options and default options
419 # hard-coded options are required and will always be there
420 # default options can be replaced by enviromental variables or command line options
421 CCFLAGS_required = []
422 LINKFLAGS_required = []
425 # under windows, scons is confused by .C/.c and uses gcc instead of
426 # g++. I am forcing the use of g++ here. This is expected to change
427 # after lyx renames all .C files to .cpp
429 # save the old c compiler and CCFLAGS (used by libintl)
430 C_COMPILER = env.subst('$CC')
431 C_CCFLAGS = env.subst('$CCFLAGS').split()
432 # if we use ms vc, the commands are fine (cl.exe and link.exe)
434 # /TP treat all source code as C++
435 # C4819: The file contains a character that cannot be represented
436 # in the current code page (number)
437 # C4996: foo was decleared deprecated
438 CCFLAGS_required.extend(['/TP', '/EHsc'])
439 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
441 if env.has_key('CXX') and env['CXX']:
442 env['CC'] = env.subst('$CXX')
443 env['LINK'] = env.subst('$CXX')
448 # for debug/release mode
449 if env.has_key('optimization') and env['optimization'] is not None:
450 # if user supplies optimization flags, use it anyway
451 CCFLAGS_required.extend(env['optimization'].split())
452 # and do not use default
453 set_default_optimization_flags = False
455 set_default_optimization_flags = True
459 CCFLAGS_required.append('/Zi')
460 LINKFLAGS_required.extend(['/debug', '/map'])
462 CCFLAGS_required.append('-g')
463 CCFLAGS_default.append('-O')
464 elif mode == 'release' and set_default_optimization_flags:
466 CCFLAGS_default.append('/O2')
468 CCFLAGS_default.append('-O2')
470 # msvc uses separate tools for profiling
471 if env.has_key('profiling') and env['profiling']:
473 print 'Visual C++ does not use profiling options'
475 CCFLAGS_required.append('-pg')
476 LINKFLAGS_required.append('-pg')
478 if env.has_key('warnings') and env['warnings']:
480 CCFLAGS_default.append('/W2')
482 # Note: autotools detect gxx version and pass -W for 3.x
483 # and -Wextra for other versions of gcc
484 CCFLAGS_default.append('-Wall')
486 # Now, set the variables as follows:
487 # 1. if command line option exists: replace default
488 # 2. then if s envronment variable exists: replace default
489 # 3. set variable to required + default
490 def setEnvVariable(env, name, required = None, default = None, split = True):
491 ''' env: environment to set variable
493 required: hardcoded options
494 default: default options that can be replaced by command line or
495 environment variables
496 split: whether or not split obtained variable like '-02 -g'
498 # first try command line argument (override environment settings)
499 if ARGUMENTS.has_key(name):
500 default = ARGUMENTS[name]
502 default = default.split()
503 # then use environment default
504 elif os.environ.has_key(name):
505 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
506 default = os.environ[name]
508 default = default.split()
510 if required is not None:
512 if default is not None:
513 if env.has_key(name) and env[name] != default:
518 setEnvVariable(env, 'DESTDIR', split=False)
519 setEnvVariable(env, 'CC')
520 setEnvVariable(env, 'LINK')
521 setEnvVariable(env, 'CPP')
522 setEnvVariable(env, 'CXX')
523 setEnvVariable(env, 'CXXCPP')
524 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
525 setEnvVariable(env, 'CXXFLAGS')
526 setEnvVariable(env, 'CPPFLAGS')
527 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
529 # if DESTDIR is not set...
530 if env.has_key('dest_dir'):
531 print "This option is obsolete. Please use DESTDIR instead."
532 env['DESTDIR'] = env['dest_dir']
535 #---------------------------------------------------------
536 # Frontend related variables (QTDIR etc)
537 #---------------------------------------------------------
539 if env.has_key('qt_dir') and env['qt_dir']:
540 env['QTDIR'] = env['qt_dir']
541 # add path to the qt tools
542 env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
543 # set environment so that moc etc can be found even if its path is not set properly
544 env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
545 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
546 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
548 # QTDIR is not always used so no warning is issued.
549 env['QTDIR'] = 'QTDIR_is_not_defined'
551 if env.has_key('qt_lib_path') and env['qt_lib_path']:
552 qt_lib_path = env.subst('$qt_lib_path')
553 elif 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 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.
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]
1272 print "Can not locate qt tools"
1273 print "What I get is "
1274 print " QTDIR: ", env['QTDIR']
1277 if platform_name in ['win32', 'cygwin']:
1278 # the final link step needs stdc++ to succeed under mingw
1279 # FIXME: shouldn't g++ automatically link to stdc++?
1281 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1283 system_libs = ['shlwapi', 'stdc++', 'z']
1284 elif platform_name == 'cygwin' and env['X11']:
1285 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1286 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1292 ('HAVE_ICONV', env['ICONV_LIB']),
1293 ('HAVE_LIBGDI32', 'gdi32'),
1294 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1295 ('USE_ASPELL', aspell_lib),
1296 ('USE_ISPELL', 'ispell'),
1297 ('USE_PSPELL', 'pspell'),
1302 system_libs.append(lib[1])
1305 # Build parameters CPPPATH etc
1308 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1311 # boost: for boost header files
1312 # BUILDDIR/common: for config.h
1313 # TOP_SRCDIR/src: for support/* etc
1315 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$BUILDDIR/common', '$TOP_SRCDIR/src']
1316 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1317 if env['nls'] and included_gettext:
1318 env['CPPPATH'].append('$BUILDDIR/intl')
1320 # QT_INC_PATH is not needed for *every* source file
1321 env['CPPPATH'].remove(qt_inc_path)
1324 # A Link script for cygwin see
1325 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1326 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1329 if platform_name == 'cygwin':
1330 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1331 ld_script = utils.installCygwinLDScript(ld_script_path)
1332 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1333 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1338 # fill in the version info
1339 env['VERSION_INFO'] = '''Configuration
1341 Special build flags: %s
1343 C Compiler flags: %s %s
1345 C++ Compiler LyX flags: %s
1346 C++ Compiler flags: %s %s
1348 Linker user flags: %s
1350 Builing directory: %s
1351 Local library directory: %s
1354 Frontend libraries: %s
1355 System libraries: %s
1356 include search path: %s
1362 ''' % (platform_name,
1363 env.subst('$CCFLAGS'), env.subst('$CC'),
1364 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1365 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1366 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1367 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1368 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1369 str(env['LIBPATH']), str(boost_libraries),
1370 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1371 frontend, packaging_method,
1372 prefix, env['LYX_DIR'])
1374 if frontend in ['qt2', 'qt3', 'qt4']:
1375 env['VERSION_INFO'] += ''' include dir: %s
1378 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1381 print env['VERSION_INFO']
1384 # Mingw command line may be too short for our link usage,
1385 # Here we use a trick from scons wiki
1386 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1388 # I also would like to add logging (commands only) capacity to the
1390 logfile = env.get('logfile', default_log_file)
1391 if logfile != '' or platform_name == 'win32':
1393 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1394 info = '''# This is a log of commands used by scons to build lyx
1398 ''' % (time.asctime(), ' '.join(sys.argv),
1399 env['VERSION_INFO'].replace('\n','\n# ')) )
1404 # -h will print out help info
1405 Help(opts.GenerateHelpText(env))
1407 # save environment settings (for fast_start option)
1408 cache_file = open(env_cache_file, 'w')
1409 cPickle.dump(env_cache, cache_file)
1413 #----------------------------------------------------------
1415 #----------------------------------------------------------
1416 # this has been the source of problems on some platforms...
1417 # I find that I need to supply it with full path name
1418 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1419 # this usage needs further investigation.
1420 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1422 print "Building all targets recursively"
1424 if env.has_key('rebuild'):
1425 rebuild_targets = env['rebuild'].split(',')
1427 rebuild_targets = None
1429 def libExists(libname):
1430 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1431 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1433 targets = BUILD_TARGETS
1434 # msvc need to pass full target name, so I have to look for path/lyx etc
1435 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1436 or 'install' in targets or 'all' in targets
1437 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1438 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1439 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1440 build_mathed = build_lyx or 'mathed' in targets
1441 build_insets = build_lyx or 'insets' in targets
1442 build_frontends = build_lyx or 'frontends' in targets
1443 build_graphics = build_lyx or 'graphics' in targets
1444 build_controllers = build_lyx or 'controllers' in targets
1445 build_client = True in ['client' in x for x in targets] \
1446 or 'install' in targets or 'all' in targets
1447 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1448 or 'install' in targets or 'all' in targets
1449 build_lyxbase = build_lyx or 'lyxbase' in targets
1450 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1451 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1452 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1453 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1454 build_msvs_projects = use_vc and 'msvs_projects' in targets
1457 # now, if rebuild_targets is specified, do not rebuild some targets
1458 rebuild_targets = rebuild_targets
1460 def ifBuildLib(name, libname, old_value):
1461 # explicitly asked to rebuild
1462 if name in rebuild_targets:
1464 # else if not rebuild, and if the library already exists
1465 elif libExists(libname):
1467 # do not change the original value
1470 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1471 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1472 build_support = ifBuildLib('support', 'support', build_support)
1473 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1474 build_insets = ifBuildLib('insets', 'insets', build_insets)
1475 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1476 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1477 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1478 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1479 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1480 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1481 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1483 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1497 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1499 boostenv = env.Copy()
1501 # boost use its own config.h
1502 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1503 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1505 for lib in boost_libs:
1506 print 'Processing files in boost/libs/%s/src...' % lib
1507 boostlib = boostenv.StaticLibrary(
1508 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1509 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1510 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1512 Alias('boost', boostlib)
1519 intlenv = env.Copy()
1521 print "Processing files in intl..."
1523 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1525 # we need the original C compiler for these files
1526 intlenv['CC'] = C_COMPILER
1527 intlenv['CCFLAGS'] = C_CCFLAGS
1529 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1530 # intl does not use global config.h
1531 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1533 intlenv.Append(CCFLAGS = [
1534 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1535 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1536 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1538 '-DENABLE_RELOCATABLE=1',
1540 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1542 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1543 '-Drelocate=libintl_relocate',
1544 '-DDEPENDS_ON_LIBICONV=1',
1549 intl = intlenv.StaticLibrary(
1550 target = '$LOCALLIBPATH/included_intl',
1552 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1553 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1554 build_dir = '$BUILDDIR/intl')
1560 # Now, src code under src/
1562 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1569 print "Processing files in src/support..."
1571 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1573 support = env.StaticLibrary(
1574 target = '$LOCALLIBPATH/support',
1575 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1576 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1577 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1579 Alias('support', support)
1586 print "Processing files in src/mathed..."
1588 mathed = env.StaticLibrary(
1589 target = '$LOCALLIBPATH/mathed',
1590 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1592 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1593 build_dir = '$BUILDDIR/common/mathed')
1595 Alias('mathed', mathed)
1602 print "Processing files in src/insets..."
1604 insets = env.StaticLibrary(
1605 target = '$LOCALLIBPATH/insets',
1606 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1608 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1610 Alias('insets', insets)
1617 print "Processing files in src/frontends..."
1619 frontends = env.StaticLibrary(
1620 target = '$LOCALLIBPATH/frontends',
1621 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1622 build_dir = '$BUILDDIR/common/frontends')
1624 Alias('frontends', frontends)
1631 print "Processing files in src/graphics..."
1633 graphics = env.StaticLibrary(
1634 target = '$LOCALLIBPATH/graphics',
1635 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1636 build_dir = '$BUILDDIR/common/graphics')
1638 Alias('graphics', graphics)
1641 if build_controllers:
1643 # src/frontends/controllers
1645 print "Processing files in src/frontends/controllers..."
1647 controllers = env.StaticLibrary(
1648 target = '$LOCALLIBPATH/controllers',
1649 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1650 build_dir = '$BUILDDIR/common/frontends/controllers')
1652 Alias('controllers', controllers)
1656 # src/frontend/qt2/3/4
1658 if build_qt2 or build_qt3 or build_qt4:
1659 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1663 print "Processing files in src/frontends/qt2..."
1666 # disable auto scan to speed up non build time
1667 qt2env['QT_AUTOSCAN'] = 0
1668 qt2env['QT_MOCHPREFIX'] = ''
1673 qt2env.AppendUnique(CPPPATH = [
1675 '$BUILDDIR/common/images',
1676 '$BUILDDIR/common/frontends',
1677 '$BUILDDIR/common/frontends/qt2',
1678 '$BUILDDIR/common/frontends/controllers',
1682 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1685 FileDialog_private.C
1724 QSpellcheckerDialog.C
1726 QTabularCreateDialog.C
1741 # manually moc and uic files for better performance
1742 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1744 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1745 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1747 qt2_uiced_cc_files = []
1748 for x in qt2_uiced_files:
1749 qt2_uiced_cc_files.extend(x[1:])
1751 qt2 = qt2env.StaticLibrary(
1752 target = '$LOCALLIBPATH/qt2',
1753 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1754 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1760 print "Processing files in src/frontends/qt3..."
1763 # disable auto scan to speed up non build time
1764 qt3env['QT_AUTOSCAN'] = 0
1765 qt3env['QT_MOCHPREFIX'] = ''
1770 qt3env.AppendUnique(CPPPATH = [
1772 '$BUILDDIR/common/images',
1773 '$BUILDDIR/common/frontends',
1774 '$BUILDDIR/common/frontends/qt3',
1775 '$BUILDDIR/common/frontends/controllers',
1779 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1782 FileDialog_private.C
1822 QSpellcheckerDialog.C
1824 QTabularCreateDialog.C
1839 # manually moc and uic files for better performance
1840 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1842 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1843 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1845 qt3_uiced_cc_files = []
1846 for x in qt3_uiced_files:
1847 qt3_uiced_cc_files.extend(x[1:])
1849 qt3 = qt3env.StaticLibrary(
1850 target = '$LOCALLIBPATH/qt3',
1851 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1852 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1858 print "Processing files in src/frontends/qt4..."
1861 qt4env['QT_AUTOSCAN'] = 0
1863 # local qt4 toolset from
1864 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1866 # NOTE: I have to patch qt4.py since it does not automatically
1867 # process .C file!!! (add to cxx_suffixes )
1869 qt4env.Tool('qt4', [scons_dir])
1870 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1872 qt4env.AppendUnique(CPPPATH = [
1874 '$BUILDDIR/common/images',
1875 '$BUILDDIR/common/frontends',
1876 '$BUILDDIR/common/frontends/qt4',
1877 '$BUILDDIR/common/frontends/controllers',
1882 # FIXME: replace by something from pkg_config
1883 qt4env.Append(CCFLAGS = [
1885 '-DQT_CLEAN_NAMESPACE',
1893 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1896 FileDialog_private.C
1939 QSpellcheckerDialog.C
1941 QTabularCreateDialog.C
1960 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1961 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1962 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1965 # moc qt4_moc_files, the moced files are included in the original files
1967 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1969 qt4 = qt4env.StaticLibrary(
1970 target = '$LOCALLIBPATH/qt4',
1971 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1972 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1981 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1983 print "Processing files in src/client..."
1985 if env['HAVE_FCNTL']:
1986 client = env.Program(
1987 target = '$BUILDDIR/common/client/lyxclient',
1988 LIBS = ['support'] + intl_libs + system_libs +
1989 socket_libs + boost_libraries,
1990 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1991 build_dir = '$BUILDDIR/common/client')
1993 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1994 client, [Copy('$TARGET', '$SOURCE')]))
1997 Alias('client', client)
2004 print "Processing files in src/tex2lyx..."
2006 tex2lyx_env = env.Copy()
2008 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2009 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2011 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2012 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2013 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2014 [Copy('$TARGET', '$SOURCE')])
2016 tex2lyx = tex2lyx_env.Program(
2017 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2018 LIBS = ['support'] + boost_libraries + system_libs,
2019 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2020 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2021 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2022 build_dir = '$BUILDDIR/common/tex2lyx')
2024 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2025 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2026 Alias('tex2lyx', tex2lyx)
2033 print "Processing files in src..."
2035 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2037 lyx_post_source = Split('''
2046 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2047 lyx_post_source.append('aspell.C')
2048 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2049 lyx_post_source.append('pspell.C')
2050 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2051 lyx_post_source.append('ispell.C')
2053 # msvc requires at least one source file with main()
2054 # so I exclude main.C from lyxbase
2055 lyxbase_pre = env.StaticLibrary(
2056 target = '$LOCALLIBPATH/lyxbase_pre',
2057 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2058 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2059 'ispell.C', 'Variables.C', 'Sectioning.C'],
2060 include = ['version.C'], build_dir = '$BUILDDIR/common')
2062 lyxbase_post = env.StaticLibrary(
2063 target = '$LOCALLIBPATH/lyxbase_post',
2064 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2066 Alias('lyxbase', lyxbase_pre)
2067 Alias('lyxbase', lyxbase_post)
2072 # Build lyx with given frontend
2075 target = '$BUILDDIR/$frontend/lyx',
2076 source = ['$BUILDDIR/common/main.C'],
2094 # [/path/to/lyx.ext] => lyx-qt3.ext
2095 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2096 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2097 [Copy('$TARGET', '$SOURCE')]))
2101 if build_msvs_projects:
2102 def build_project(target, dir, full_target = None,
2103 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2104 ''' build mavs project files
2105 target: alias (correspond to directory name)
2106 dir: source directory or directories (a list)
2107 full_target: full path/filename of the target
2108 src_pattern: glob pattern
2109 include: files to include into source
2110 resource: directory or directories with resource (.ui) files
2111 rebuildTargetOnly: whether or not only rebuild this target
2113 For non-debug-able targets like static libraries, target (alias) is
2114 enough to build the target. For executable targets, msvs need to know
2115 the full path to start debug them.
2117 if resource is not None:
2118 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2119 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2122 if rebuildTargetOnly:
2123 cmds = 'faststart=yes rebuild='+target
2125 cmds = 'faststart=yes'
2126 if type(dir) == type([]):
2130 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2131 pattern = src_pattern, include = include,
2132 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2133 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2135 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2137 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2138 pattern = src_pattern, include = include,
2139 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2140 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2142 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2143 if full_target is None:
2144 build_target = target
2146 build_target = full_target
2148 proj = env.MSVSProject(
2149 target = target + env['MSVSPROJECTSUFFIX'],
2151 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2154 buildtarget = build_target,
2158 Alias('msvs_projects', proj)
2160 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2161 src_pattern = '*.cpp')
2163 build_project('intl', 'intl', src_pattern = '*.c')
2165 build_project('support', 'src/support', include=['package.C.in'])
2167 build_project('mathed', 'src/mathed')
2169 build_project('insets', 'src/insets')
2171 build_project('frontends', 'src/frontends')
2173 build_project('graphics', 'src/graphics')
2175 build_project('controllers', 'src/frontends/controllers')
2177 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2179 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2181 build_project('client', 'src/client', rebuildTargetOnly = False,
2182 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2184 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2185 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2187 build_project('lyxbase', 'src')
2189 if frontend == 'qt3':
2190 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2191 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2192 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2193 rebuildTargetOnly = False,
2194 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2196 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2197 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2198 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2199 rebuildTargetOnly = False,
2200 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2207 print 'Processing files in po...'
2212 # files to translate
2213 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2214 # possibly *only* handle these languages
2216 if env.has_key('languages'):
2217 languages = env.make_list(env['lanauges'])
2218 # use defulat msgfmt
2219 if not env['MSGFMT']:
2220 print 'msgfmt does not exist. Can not process po files'
2223 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2226 for f in transfiles:
2228 fname = os.path.split(f)[1]
2230 country = fname.split('.')[0]
2232 if not languages or country in languages:
2233 gmo_files.extend(env.Transfiles(f))
2236 if 'install' in targets:
2238 # install to DESTDIR or prefix
2239 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2240 # if dest_dir is different from prefix.
2241 if env.has_key('exec_prefix'):
2242 bin_dest_dir = Dir(env['exec_prefix']).abspath
2244 bin_dest_dir = os.path.join(dest_dir, 'bin')
2246 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2248 share_dest_dir = os.path.join(dest_dir, share_dir)
2249 man_dest_dir = os.path.join(dest_dir, man_dir)
2250 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2251 # create the directory if needed
2252 if not os.path.isdir(dest_dir):
2254 os.makedirs(dest_dir)
2257 if not os.path.isdir(dest_dir):
2258 print 'Can not create directory', dest_dir
2263 # do not install these files
2264 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2265 'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
2267 def install(dest, src):
2268 ''' recusive installation of src to dest '''
2269 # separate file and directory
2270 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2271 dirs = filter(os.path.isdir, src)
2273 env.Install(dest, files)
2277 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2278 glob.glob(os.path.join(dir, '*'))) )
2281 # executables (some of them may be none)
2284 version_suffix = program_suffix
2289 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2290 target = os.path.join(bin_dest_dir, target_name)
2291 env.InstallAs(target, lyx)
2292 Alias('install', target)
2293 # install lyx as lyx-qt3
2294 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2295 target = os.path.join(bin_dest_dir, target_name)
2296 env.InstallAs(target, lyx)
2297 Alias('install', target)
2300 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2301 target = os.path.join(bin_dest_dir, target_name)
2302 env.InstallAs(target, tex2lyx)
2303 Alias('install', target)
2305 # install lyxclient, may not exist
2307 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2308 target = os.path.join(bin_dest_dir, target_name)
2309 env.InstallAs(target, client)
2310 Alias('install', target)
2313 dirs = install(share_dest_dir,
2314 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2315 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2316 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2317 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2319 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2320 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2321 Alias('install', dirs)
2323 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2324 env.subst('$TOP_SRCDIR/lyx.man'))
2325 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2326 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2327 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2328 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2329 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2330 x in ['lyx', 'tex2lyx', 'lyxclient']])
2332 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2333 for gmo in gmo_files:
2334 lan = os.path.split(str(gmo))[1].split('.')[0]
2335 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2336 env.InstallAs(dest_file, gmo)
2337 Alias('install', dest_file)
2341 Alias('all', ['lyx', 'client', 'tex2lyx'])