1 # vi:filetype=python:expandtab:tabstop=2:shiftwidth=2
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 # config/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 'scons -f development/scons/SConstruct'
33 if os.path.isfile('SConstruct'):
36 # called as 'cd development/scons; scons'
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),
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 # enable glib, (config.h has _GLIBCXX_CONCEPT_CHECKS)
156 BoolOption('concept_checks', 'Enable concept checks', True),
158 BoolOption('nls', 'Whether or not use native language support', True),
159 # FIXME: not implemented
160 BoolOption('profile', '(NA) Whether or not enable profiling', False),
161 # FIXME: not implemented
162 BoolOption('std_debug', '(NA) Whether or not turn on stdlib debug', False),
164 BoolOption('X11', 'Use x11 windows system', default_with_x),
165 # use MS VC++ to build lyx
166 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
168 PathOption('qt_dir', 'Path to qt directory', None),
170 PathOption('qt_include_path', 'Path to qt include directory', None),
172 PathOption('qt_lib_path', 'Path to qt library directory', None),
173 # build directory, will use $mode if not set
174 PathOption('build_dir', 'Build directory', None),
175 # extra include and libpath
176 PathOption('extra_inc_path', 'Extra include path', None),
178 PathOption('extra_lib_path', 'Extra library path', None),
180 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
182 PathOption('extra_inc_path1', 'Extra include path', None),
184 PathOption('extra_lib_path1', 'Extra library path', None),
185 # rebuild only specifed, comma separated targets
186 ('rebuild', 'rebuild only specifed, comma separated targets', None),
187 # can be set to a non-existing directory
188 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
190 ('version_suffix', 'install lyx as lyx-suffix', None),
191 # how to load options
192 ('load_option', '''load option from previous scons run. option can be
193 yes (default): load all options
194 no: do not load any option
195 opt1,opt2: load specified options
196 -opt1,opt2: load all options other than specified ones''', 'yes'),
198 ('optimization', 'optimization CCFLAGS option.', None),
200 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
202 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
203 # provided for backward compatibility
204 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
205 # environment variable can be set as options.
206 ('DESTDIR', 'install to DESTDIR', None),
207 ('CC', 'replace default $CC', None),
208 ('LINK', 'replace default $LINK', None),
209 ('CPP', 'replace default $CPP', None),
210 ('CXX', 'replace default $CXX', None),
211 ('CXXCPP', 'replace default $CXXCPP', None),
212 ('CCFLAGS', 'replace default $CCFLAGS', None),
213 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
214 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
217 # copied from SCons/Options/BoolOption.py
218 # We need to use them before a boolean ARGUMENTS option is available
220 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
221 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
223 # whether or not use current config.h, and cached tests
225 # if fast_start=yes (default), load variables from env_cache_file
226 if (not ARGUMENTS.has_key('fast_start') or \
227 ARGUMENTS['fast_start'] in true_strings) \
228 and os.path.isfile(env_cache_file):
230 cache_file = open(env_cache_file)
231 env_cache = cPickle.load(cache_file)
233 print '------------ fast_start mode --------------------'
234 print ' Use cached test results and current config.h'
235 print ' use fast_start=no to override'
241 # if load_option=yes (default), load saved comand line options
243 # This option can take value yes/no/opt1,opt2/-opt1,opt2
244 # and tries to be clever in choosing options to load
245 if (not ARGUMENTS.has_key('load_option') or \
246 ARGUMENTS['load_option'] not in false_strings) \
247 and os.path.isfile(env_cache_file):
248 cache_file = open(env_cache_file)
249 opt_cache = cPickle.load(cache_file)['arg_cache']
251 # import cached options, but we should ignore qt_dir when frontend changes
252 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
253 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
254 and opt_cache.has_key('qt_dir'):
255 opt_cache.pop('qt_dir')
256 # some options will require full rebuild
257 # these are in general things that will change src/config.h
258 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
259 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
260 ARGUMENTS[arg] != opt_cache[arg]):
262 print " ** fast_start is disabled because of the change of option", arg
265 # and we do not cache some options
266 for arg in ['fast_start', 'load_option']:
267 if opt_cache.has_key(arg):
269 # now, if load_option=opt1,opt2 or -opt1,opt2
270 if ARGUMENTS.has_key('load_option') and \
271 ARGUMENTS['load_option'] not in true_strings + false_strings:
272 # if -opt1,opt2 is specified, do not load these options
273 if ARGUMENTS['load_option'][0] == '-':
274 for arg in ARGUMENTS['load_option'][1:].split(','):
275 if opt_cache.has_key(arg):
277 # if opt1,opt2 is specified, only load specified options
279 args = ARGUMENTS['load_option'].split(',')
280 for arg in opt_cache.keys():
283 # now restore options as if entered from command line
284 for key in opt_cache.keys():
285 if not ARGUMENTS.has_key(key):
286 ARGUMENTS[key] = opt_cache[key]
287 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
291 env_cache['arg_cache'] = ARGUMENTS
294 #---------------------------------------------------------
295 # Setting up environment
296 #---------------------------------------------------------
298 # I do not really like ENV=os.environ, but you may add it
299 # here if you experience some environment related problem
300 env = Environment(options = opts)
302 # set individual variables since I do not really like ENV = os.environ
303 env['ENV']['PATH'] = os.environ.get('PATH')
304 env['ENV']['HOME'] = os.environ.get('HOME')
305 # these are defined for MSVC
306 env['ENV']['LIB'] = os.environ.get('LIB')
307 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
309 # for simplicity, use var instead of env[var]
310 frontend = env['frontend']
311 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 # only support gcc now
449 if use_pch and not use_vc:
450 CCFLAGS_required.extend(['-Winvalid-pch'])
452 # for debug/release mode
453 if env.has_key('optimization') and env['optimization'] is not None:
454 # if user supplies optimization flags, use it anyway
455 CCFLAGS_required.extend(env['optimization'].split())
456 # and do not use default
457 set_default_optimization_flags = False
459 set_default_optimization_flags = True
463 CCFLAGS_required.append('/Zi')
464 LINKFLAGS_required.extend(['/debug', '/map'])
466 CCFLAGS_required.append('-g')
467 CCFLAGS_default.extend(['-Wall', '-O'])
468 elif mode == 'release' and set_default_optimization_flags:
470 CCFLAGS_default.append('/O2')
472 CCFLAGS_default.append('-O2')
474 # Now, set the variables as follows:
475 # 1. if command line option exists: replace default
476 # 2. then if s envronment variable exists: replace default
477 # 3. set variable to required + default
478 def setEnvVariable(env, name, required = None, default = None, split = True):
479 ''' env: environment to set variable
481 required: hardcoded options
482 default: default options that can be replaced by command line or
483 environment variables
484 split: whether or not split obtained variable like '-02 -g'
486 # first try command line argument (override environment settings)
487 if ARGUMENTS.has_key(name):
488 default = ARGUMENTS[name]
490 default = default.split()
491 # then use environment default
492 elif os.environ.has_key(name):
493 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
494 default = os.environ[name]
496 default = default.split()
498 if required is not None:
500 if default is not None:
501 if env.has_key(name):
506 setEnvVariable(env, 'DESTDIR', split=False)
507 setEnvVariable(env, 'CC')
508 setEnvVariable(env, 'LINK')
509 setEnvVariable(env, 'CPP')
510 setEnvVariable(env, 'CXX')
511 setEnvVariable(env, 'CXXCPP')
512 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
513 setEnvVariable(env, 'CXXFLAGS')
514 setEnvVariable(env, 'CPPFLAGS')
515 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
517 # if DESTDIR is not set...
518 if env.has_key('dest_dir'):
519 print "This option is obsolete. Please use DESTDIR instead."
520 env['DESTDIR'] = env['dest_dir']
521 dest_dir = env.get('DESTDIR', prefix)
523 #---------------------------------------------------------
524 # Frontend related variables (QTDIR etc)
525 #---------------------------------------------------------
527 if env.has_key('qt_dir') and env['qt_dir']:
528 env['QTDIR'] = env['qt_dir']
529 # add path to the qt tools
530 env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
531 # set environment so that moc etc can be found even if its path is not set properly
532 env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
534 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
536 if env.has_key('qt_lib_path') and env['qt_lib_path']:
537 qt_lib_path = env.subst('$qt_lib_path')
539 qt_lib_path = env.subst('$QTDIR/lib')
540 env.AppendUnique(LIBPATH = [qt_lib_path])
541 # qt4 seems to be using pkg_config
542 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
544 if env.has_key('qt_inc_path') and env['qt_inc_path']:
545 qt_inc_path = env['qt_inc_path']
546 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
547 qt_inc_path = '$QTDIR/include'
548 # this is the path for cygwin.
549 elif os.path.isdir('/usr/include/' + frontend):
550 qt_inc_path = '/usr/include/$frontend'
552 print "Qt include directory not found. Please specify it using qt_inc_path"
554 # Note that this CPPPATH is for testing only
555 # it will be removed before calling SConscript
556 env['CPPPATH'] = [qt_inc_path]
559 # extra_inc_path and extra_lib_path
562 if env.has_key('extra_inc_path') and env['extra_inc_path']:
563 extra_inc_paths.append(env['extra_inc_path'])
564 if env.has_key('extra_lib_path') and env['extra_lib_path']:
565 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
566 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
567 extra_inc_paths.append(env['extra_inc_path1'])
568 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
569 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
570 if env.has_key('extra_bin_path') and env['extra_bin_path']:
571 # maybe only one of them is needed
572 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
573 env['ENV']['PATH'] += os.pathsep + env['extra_bin_path']
574 # extra_inc_paths will be used later by intlenv etc
575 env.AppendUnique(CPPPATH = extra_inc_paths)
578 #----------------------------------------------------------
580 #----------------------------------------------------------
582 conf = Configure(env,
584 'CheckPkgConfig' : utils.checkPkgConfig,
585 'CheckPackage' : utils.checkPackage,
586 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
587 'CheckSelectArgType' : utils.checkSelectArgType,
588 'CheckBoostLibraries' : utils.checkBoostLibraries,
589 'CheckCommand' : utils.checkCommand,
590 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
591 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
595 # pkg-config? (if not, we use hard-coded options)
597 if conf.CheckPkgConfig('0.15.0'):
598 env['HAS_PKG_CONFIG'] = True
600 print 'pkg-config >= 0.1.50 is not found'
601 env['HAS_PKG_CONFIG'] = False
602 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
604 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
606 # zlib? This is required. (fast_start assumes the existance of zlib)
608 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
609 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
610 print 'Did not find zdll.lib or zlib.h, exiting!'
616 # qt3 does not use pkg_config
617 if frontend in ['qt2', 'qt3']:
618 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
619 print 'Did not find qt libraries, exiting!'
621 elif frontend == 'qt4':
623 # first: try pkg_config
624 if env['HAS_PKG_CONFIG']:
625 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
626 env['QT4_PKG_CONFIG'] = succ
627 # second: try to link to it
629 # FIXME: under linux, I can test the following perfectly
630 # However, under windows, lib names need to passed as libXXX4.a ...
631 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
632 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
633 # third: try to look up the path
636 for lib in ['QtCore', 'QtGui']:
637 # windows version has something like QtGui4 ...
638 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
639 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
642 # still can not find it
644 print "Qt4 libraries are found."
646 print 'Did not find qt libraries, exiting!'
649 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
651 # glob file xxx.dll.manifest (msvc 2003 may not have it)
652 manifests = glob.glob(os.path.join(qt_lib_path, '*.dll.manifest'))
654 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifests[0]]
659 if conf.CheckLib('socket'):
660 socket_libs.append('socket')
661 # nsl is the network services library and provides a
662 # transport-level interface to networking services.
663 if conf.CheckLib('nsl'):
664 socket_libs.append('nsl')
665 env_cache['SOCKET_LIBS'] = socket_libs
667 socket_libs = env_cache['SOCKET_LIBS']
669 # check available boost libs (since lyx1.4 does not use iostream)
671 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
672 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
673 boost_libs.append(lib)
676 # check boost libraries
677 boost_opt = ARGUMENTS.get('boost', 'auto')
678 # check for system boost
679 paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
682 # here I assume that all libraries are in the same directory
683 for lib in boost_libs:
684 if boost_opt == 'included':
685 boost_libraries.append('included_boost_%s' % lib)
686 env['INCLUDED_BOOST'] = True
687 elif boost_opt == 'auto':
688 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
691 boost_libraries.append('included_boost_%s' % lib)
692 env['INCLUDED_BOOST'] = True
694 boost_libraries.append(res[1])
695 env['INCLUDED_BOOST'] = False
696 boost_libpath = res[0]
697 elif boost_opt == 'system':
698 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
700 print "Can not find system boost libraries"
701 print "Please supply a path through extra_lib_path and try again."
702 print "Or use boost=included to use included boost libraries."
705 boost_libraries.append(res[1])
706 env.AppendUnique(LIBPATH = [res[0]])
707 boost_libpath = res[0]
708 env_cache['BOOST_LIBRARIES'] = boost_libraries
709 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
710 env_cache['BOOST_LIBPATH'] = boost_libpath
712 boost_libraries = env_cache['BOOST_LIBRARIES']
713 if env_cache['BOOST_LIBPATH'] is not None:
714 env.AppendUnique(LIBPATH = [env_cache['BOOST_LIBPATH']])
715 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
718 env['ENABLE_NLS'] = env['nls']
721 if not env['ENABLE_NLS']:
723 included_gettext = False
725 # check gettext libraries
726 gettext_opt = ARGUMENTS.get('gettext', 'auto')
727 # check for system gettext
729 if gettext_opt in ['auto', 'system']:
730 if conf.CheckLib('intl'):
731 included_gettext = False
735 if gettext_opt == 'system':
736 print "Can not find system gettext library"
737 print "Please supply a path through extra_lib_path and try again."
738 print "Or use gettext=included to use included gettext libraries."
740 # now, auto and succ = false, or gettext=included
742 # we do not need to set LIBPATH now.
743 included_gettext = True
744 intl_libs = ['included_intl']
745 env_cache['INCLUDED_GETTEXT'] = included_gettext
746 env_cache['INTL_LIBS'] = intl_libs
748 intl_libs = env_cache['INTL_LIBS']
749 included_gettext = env_cache['INCLUDED_GETTEXT']
752 # check for msgfmt command
754 env['MSGFMT'] = conf.CheckCommand('msgfmt')
755 env_cache['MSGFMT'] = env['MSGFMT']
757 env['MSGFMT'] = env_cache['MSGFMT']
760 #----------------------------------------------------------
761 # Generating config.h
762 #----------------------------------------------------------
763 aspell_lib = 'aspell'
764 # assume that we use aspell, aspelld compiled for msvc
765 if platform_name == 'win32' and mode == 'debug':
766 aspell_lib = 'aspelld'
769 print "Generating src/config.h..."
771 # AIKSAURUS_H_LOCATION
772 if (conf.CheckCXXHeader("Aiksaurus.h")):
773 aik_location = '<Aiksaurus.h>'
774 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
775 aik_location = '<Aiksaurus/Aiksaurus.h>'
779 # determine headers to use
780 spell_opt = ARGUMENTS.get('spell', 'auto')
781 env['USE_ASPELL'] = False
782 env['USE_PSPELL'] = False
783 env['USE_ISPELL'] = False
784 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
785 spell_engine = 'USE_ASPELL'
786 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
787 spell_engine = 'USE_PSPELL'
788 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
789 spell_engine = 'USE_ISPELL'
793 if spell_engine is not None:
794 env[spell_engine] = True
796 if spell_opt == 'auto':
797 print "Warning: Can not locate any spell checker"
798 elif spell_opt != 'no':
799 print "Warning: Can not locate specified spell checker:", spell_opt
802 # check arg types of select function
803 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
807 result = utils.createConfigFile(conf,
808 config_file = os.path.join(top_src_dir, 'src', 'config.h'),
809 config_pre = '''/* src/config.h. Generated by SCons. */
814 * This file is part of LyX, the document processor.
815 * Licence details can be found in the file COPYING.
817 * This is the compilation configuration file for LyX.
818 * It was generated by scon.
819 * You might want to change some of the defaults if something goes wrong
820 * during the compilation.
827 ('io.h', 'HAVE_IO_H', 'c'),
828 ('limits.h', 'HAVE_LIMITS_H', 'c'),
829 ('locale.h', 'HAVE_LOCALE_H', 'c'),
830 ('locale', 'HAVE_LOCALE', 'cxx'),
831 ('process.h', 'HAVE_PROCESS_H', 'c'),
832 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
833 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
834 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
835 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
836 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
837 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
838 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
839 ('utime.h', 'HAVE_UTIME_H', 'c'),
840 ('direct.h', 'HAVE_DIRECT_H', 'c'),
841 ('istream', 'HAVE_ISTREAM', 'cxx'),
842 ('ostream', 'HAVE_OSTREAM', 'cxx'),
843 ('ios', 'HAVE_IOS', 'cxx'),
846 ('open', 'HAVE_OPEN', None),
847 ('close', 'HAVE_CLOSE', None),
848 ('popen', 'HAVE_POPEN', None),
849 ('pclose', 'HAVE_PCLOSE', None),
850 ('_open', 'HAVE__OPEN', None),
851 ('_close', 'HAVE__CLOSE', None),
852 ('_popen', 'HAVE__POPEN', None),
853 ('_pclose', 'HAVE__PCLOSE', None),
854 ('getpid', 'HAVE_GETPID', None),
855 ('_getpid', 'HAVE__GETPID', None),
856 ('mkdir', 'HAVE_MKDIR', None),
857 ('_mkdir', 'HAVE__MKDIR', None),
858 ('mktemp', 'HAVE_MKTEMP', None),
859 ('mkstemp', 'HAVE_MKSTEMP', None),
860 ('strerror', 'HAVE_STRERROR', None),
861 ('count', 'HAVE_STD_COUNT', '''
866 return std::count(a, a+5, 'l');
869 ('getcwd', 'HAVE_GETCWD', None),
870 ('setenv', 'HAVE_SETENV', None),
871 ('putenv', 'HAVE_PUTENV', None),
872 ('fcntl', 'HAVE_FCNTL', None),
875 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
876 '#include <streambuf>\n#include <istream>')
879 ('gdi32', 'HAVE_LIBGDI32'),
880 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
881 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
884 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
886 'Define is sys/types.h does not have pid_t',
890 (conf.CheckCXXGlobalCstd(),
892 'Define if your C++ compiler puts C library functions in the global namespace'
894 (conf.CheckMkdirOneArg(),
895 'MKDIR_TAKES_ONE_ARG',
896 'Define if mkdir takes only one argument.'
898 (conf.CheckLC_MESSAGES(),
900 'Define if your <locale.h> file defines LC_MESSAGES.'
902 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
903 (env.has_key('assertions') and env['assertions'],
905 'Define if you want assertions to be enabled in the code'
907 (env.has_key('nls') and env['nls'],
909 "Define to 1 if translation of program messages to the user's native anguage is requested.",
911 (env.has_key('warnings') and env['warnings'],
913 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
915 (env.has_key('concept_checks') and env['concept_checks'],
916 '_GLIBCXX_CONCEPT_CHECKS',
917 'libstdc++ concept checking'
919 (os.name != 'nt', 'BOOST_POSIZ',
920 'Indicates to boost which API to use (posix or windows).'
922 (spell_engine is not None, spell_engine,
923 'Spell engine to use'
927 ('#define PACKAGE "%s%s"' % (package, program_suffix),
929 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
930 'Define to the address where bug reports for this package should be sent.'),
931 ('#define PACKAGE_NAME "%s"' % package_name,
932 'Define to the full name of this package.'),
933 ('#define PACKAGE_STRING "%s"' % package_string,
934 'Define to the full name and version of this package.'),
935 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
936 'Define to the one symbol short name of this package.'),
937 ('#define PACKAGE_VERSION "%s"' % package_version,
938 'Define to the version of this package.'),
939 ('#define BOOST_ALL_NO_LIB 1',
940 'disable automatic linking of boost libraries.'),
941 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
943 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
944 'Aiksaurus include file'),
945 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
946 "Define to the type of arg 1 for `select'."),
947 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
948 "Define to the type of arg 2, 3, 4 for `select'."),
949 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
950 "Define to the type of arg 5 for `select'."),
952 config_post = '''/************************************************************
953 ** You should not need to change anything beyond this point */
955 #ifndef HAVE_STRERROR
956 #if defined(__cplusplus)
959 char * strerror(int n);
963 #ifndef HAVE_DECL_MKSTEMP
964 #if defined(__cplusplus)
971 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
972 # define USE_BOOST_FORMAT 1
974 # define USE_BOOST_FORMAT 0
977 #define BOOST_USER_CONFIG <config.h>
979 #if !defined(ENABLE_ASSERTIONS)
980 # define BOOST_DISABLE_ASSERTS 1
982 #define BOOST_ENABLE_ASSERT_HANDLER 1
984 #define BOOST_DISABLE_THREADS 1
985 #define BOOST_NO_WREGEX 1
986 #define BOOST_NO_WSTRING 1
989 # define BOOST_POSIX 1
992 #if defined(HAVE_NEWAPIS_H)
993 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
1000 # these keys are needed in env
1001 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1002 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1003 'ICONV_LIB', 'AIKSAURUS_LIB']:
1004 # USE_ASPELL etc does not go through result
1005 if result.has_key(key):
1006 env[key] = result[key]
1007 env_cache[key] = env[key]
1010 # this comes as a big surprise, without this line
1011 # (doing nothing obvious), adding fast_start=yes
1012 # to a build with fast_start=no will result in a rebuild
1013 # Note that the exact header file to check does not matter
1014 # conf.CheckCHeader('io.h')
1015 # only a few variables need to be rescanned
1016 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1017 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1018 'ICONV_LIB', 'AIKSAURUS_LIB']:
1019 env[key] = env_cache[key]
1022 # Finish auto-configuration
1025 #----------------------------------------------------------
1026 # Now set up our build process accordingly
1027 #----------------------------------------------------------
1032 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1033 # in their respective directory and specialized env.
1035 if frontend in ['qt2', 'qt3']:
1036 # note: env.Tool('qt') my set QT_LIB to qt
1038 frontend_libs = ['qt-mt']
1039 elif frontend == 'qt4':
1040 qt_libs = ['QtCore', 'QtGui']
1041 # set the right lib names
1042 if platform_name == 'win32':
1044 qt_lib_suffix = 'd4'
1049 qt_lib_suffix = '_debug'
1052 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1054 print "Can not locate qt tools"
1055 print "What I get is "
1056 print " QTDIR: ", env['QTDIR']
1059 if platform_name in ['win32', 'cygwin']:
1060 # the final link step needs stdc++ to succeed under mingw
1061 # FIXME: shouldn't g++ automatically link to stdc++?
1063 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1065 system_libs = ['shlwapi', 'stdc++', 'z']
1066 elif platform_name == 'cygwin' and env['X11']:
1067 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1068 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1074 ('HAVE_ICONV', env['ICONV_LIB']),
1075 ('HAVE_LIBGDI32', 'gdi32'),
1076 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1077 ('USE_ASPELL', aspell_lib),
1078 ('USE_ISPELL', 'ispell'),
1079 ('USE_PSPELL', 'pspell'),
1084 system_libs.append(lib[1])
1087 # Build parameters CPPPATH etc
1090 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1093 # boost is always in, src is needed for config.h
1095 # QT_INC_PATH is not needed for *every* source file
1096 env['CPPPATH'].remove(qt_inc_path)
1097 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$TOP_SRCDIR/src']
1100 # Customized builders
1102 # install customized builders
1103 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
1104 if use_pch and not use_vc:
1105 env['CCPCHFLAGS'] = '-x c++-header'
1106 env['BUILDERS']['PCH'] = Builder(
1107 action = '$CXX $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $SOURCES -o $TARGET',
1108 suffix = '.h.pch', src_suffix = '.h'
1112 def emptyTarget(target, source, env):
1114 env['BUILDERS']['PCH'] = Builder(action = '', emitter = emptyTarget)
1117 # A Link script for cygwin see
1118 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1119 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1122 if platform_name == 'cygwin':
1123 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1124 ld_script = utils.installCygwinLDScript(ld_script_path)
1125 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1126 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1131 # fill in the version info
1132 env['VERSION_INFO'] = '''Configuration
1134 Special build flags: %s
1136 C Compiler flags: %s %s
1138 C++ Compiler LyX flags: %s
1139 C++ Compiler flags: %s %s
1141 Linker user flags: %s
1143 Builing directory: %s
1144 Local library directory: %s
1147 Frontend libraries: %s
1148 System libraries: %s
1149 include search path: %s
1155 ''' % (platform_name,
1156 env.subst('$CCFLAGS'), env.subst('$CC'),
1157 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1158 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1159 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1160 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1161 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1162 str(env['LIBPATH']), str(boost_libraries),
1163 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1164 frontend, packaging_method,
1165 prefix, env['LYX_DIR'])
1167 if frontend in ['qt2', 'qt3', 'qt4']:
1168 env['VERSION_INFO'] += ''' include dir: %s
1171 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1174 print env['VERSION_INFO']
1177 # Mingw command line may be too short for our link usage,
1178 # Here we use a trick from scons wiki
1179 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1181 # I also would like to add logging (commands only) capacity to the
1183 logfile = env.get('logfile', default_log_file)
1184 if logfile != '' or platform_name == 'win32':
1186 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1187 info = '''# This is a log of commands used by scons to build lyx
1191 ''' % (time.asctime(), ' '.join(sys.argv),
1192 env['VERSION_INFO'].replace('\n','\n# ')) )
1197 # -h will print out help info
1198 Help(opts.GenerateHelpText(env))
1201 #----------------------------------------------------------
1203 #----------------------------------------------------------
1204 # this has been the source of problems on some platforms...
1205 # I find that I need to supply it with full path name
1206 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1207 # this usage needs further investigation.
1208 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1210 print "Building all targets recursively"
1212 if env.has_key('rebuild'):
1213 rebuild_targets = env['rebuild'].split(',')
1215 rebuild_targets = None
1217 def libExists(libname):
1218 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1219 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1221 targets = BUILD_TARGETS
1222 # msvc need to pass full target name, so I have to look for path/lyx etc
1223 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1224 or 'install' in targets or 'all' in targets
1225 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1226 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1227 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1228 build_mathed = build_lyx or 'mathed' in targets
1229 build_insets = build_lyx or 'insets' in targets
1230 build_frontends = build_lyx or 'frontends' in targets
1231 build_graphics = build_lyx or 'graphics' in targets
1232 build_controllers = build_lyx or 'controllers' in targets
1233 build_client = True in ['client' in x for x in targets] \
1234 or 'install' in targets or 'all' in targets
1235 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1236 or 'install' in targets or 'all' in targets
1237 build_lyxbase = build_lyx or 'lyxbase' in targets
1238 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1239 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1240 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1241 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1242 build_msvs_projects = use_vc and 'msvs_projects' in targets
1245 # now, if rebuild_targets is specified, do not rebuild some targets
1246 rebuild_targets = rebuild_targets
1248 def ifBuildLib(name, libname, old_value):
1249 # explicitly asked to rebuild
1250 if name in rebuild_targets:
1252 # else if not rebuild, and if the library already exists
1253 elif libExists(libname):
1255 # do not change the original value
1258 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1259 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1260 build_support = ifBuildLib('support', 'support', build_support)
1261 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1262 build_insets = ifBuildLib('insets', 'insets', build_insets)
1263 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1264 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1265 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1266 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1267 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1268 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1269 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1271 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1285 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1287 boostenv = env.Copy()
1289 boost_config_h = os.path.join(top_src_dir, 'boost', 'libs', 'config.h')
1290 if not os.path.isfile(boost_config_h) or not fast_start:
1292 print "Creating boost/config.h..."
1294 # start another configuration session.
1295 conf = Configure(boostenv,
1296 custom_tests = {'CheckMkdirOneArg' : utils.checkMkdirOneArg},
1300 result = utils.createConfigFile(conf,
1301 config_file = boost_config_h,
1302 config_pre = '''/* boost/libs/config.h. Generated by SCons. */
1307 * This file is part of LyX, the document processor.
1308 * Licence details can be found in the file COPYING.
1310 * This is the compilation configuration file for LyX.
1311 * It was generated by scon.
1312 * You might want to change some of the defaults if something goes wrong
1313 * during the compilation.
1320 ('io.h', 'HAVE_IO_H', 'c'),
1321 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1322 ('locale.h', 'HAVE_LOCALE_H', 'c'),
1323 ('locale', 'HAVE_LOCALE', 'cxx'),
1324 ('process.h', 'HAVE_PROCESS_H', 'c'),
1325 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
1326 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
1327 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
1328 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
1329 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
1330 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
1331 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1332 ('utime.h', 'HAVE_UTIME_H', 'c'),
1333 ('direct.h', 'HAVE_DIRECT_H', 'c'),
1334 ('istream', 'HAVE_ISTREAM', 'cxx'),
1335 ('ostream', 'HAVE_OSTREAM', 'cxx'),
1336 ('ios', 'HAVE_IOS', 'cxx'),
1339 ('open', 'HAVE_OPEN', None),
1340 ('close', 'HAVE_CLOSE', None),
1341 ('popen', 'HAVE_POPEN', None),
1342 ('pclose', 'HAVE_PCLOSE', None),
1343 ('_open', 'HAVE__OPEN', None),
1344 ('_close', 'HAVE__CLOSE', None),
1345 ('_popen', 'HAVE__POPEN', None),
1346 ('_pclose', 'HAVE__PCLOSE', None),
1347 ('getpid', 'HAVE_GETPID', None),
1348 ('_getpid', 'HAVE__GETPID', None),
1349 ('mkdir', 'HAVE_MKDIR', None),
1350 ('_mkdir', 'HAVE__MKDIR', None),
1351 ('mktemp', 'HAVE_MKTEMP', None),
1352 ('mkstemp', 'HAVE_MKSTEMP', None),
1353 ('strerror', 'HAVE_STRERROR', None),
1354 ('getcwd', 'HAVE_GETCWD', None),
1355 ('setenv', 'HAVE_SETENV', None),
1356 ('putenv', 'HAVE_PUTENV', None),
1357 ('fcntl', 'HAVE_FCNTL', None),
1360 (conf.CheckMkdirOneArg(),
1361 'MKDIR_TAKES_ONE_ARG',
1362 'Define if mkdir takes only one argument.'
1364 (env.has_key('assertions') and env['assertions'],
1365 'ENABLE_ASSERTIONS',
1366 'Define if you want assertions to be enabled in the code'
1368 (env.has_key('warnings') and env['warnings'],
1370 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1372 (env.has_key('concept_checks') and env['concept_checks'],
1373 '_GLIBCXX_CONCEPT_CHECKS',
1374 'libstdc++ concept checking'
1376 (os.name != 'nt', 'BOOST_POSIZ',
1377 'Indicates to boost which API to use (posix or windows).'
1381 ('#define BOOST_ALL_NO_LIB 1',
1382 'disable automatic linking of boost libraries.'),
1386 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
1387 # define USE_BOOST_FORMAT 1
1389 # define USE_BOOST_FORMAT 0
1392 #define BOOST_USER_CONFIG <config.h>
1394 #if !defined(ENABLE_ASSERTIONS)
1395 # define BOOST_DISABLE_ASSERTS 1
1397 #define BOOST_ENABLE_ASSERT_HANDLER 1
1399 #define BOOST_DISABLE_THREADS 1
1400 #define BOOST_NO_WREGEX 1
1401 #define BOOST_NO_WSTRING 1
1404 # define BOOST_POSIX 1
1412 # boost use its own config.h
1413 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$TOP_SRCDIR/boost/libs'] + extra_inc_paths
1414 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1416 for lib in boost_libs:
1417 print 'Processing files in boost/libs/%s/src...' % lib
1418 boostlib = boostenv.StaticLibrary(
1419 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1420 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1421 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1423 Alias('boost', boostlib)
1430 intlenv = env.Copy()
1432 intl_config_h = os.path.join(top_src_dir, 'intl', 'config.h')
1433 if not os.path.isfile(intl_config_h) or not fast_start:
1435 print "Creating intl/config.h..."
1437 # start another configuration session.
1438 conf = Configure(intlenv,
1440 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
1441 'CheckIconvConst' : utils.checkIconvConst,
1445 result = utils.createConfigFile(conf,
1446 config_file = intl_config_h,
1447 config_pre = '''/* intl/config.h. Generated by SCons. */
1452 * This file is part of LyX, the document processor.
1453 * Licence details can be found in the file COPYING.
1455 * This is the compilation configuration file for LyX.
1456 * It was generated by scon.
1457 * You might want to change some of the defaults if something goes wrong
1458 * during the compilation.
1465 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1466 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1467 ('string.h', 'HAVE_STRING_H', 'c'),
1468 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1469 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1470 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1471 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1472 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1473 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1474 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1477 ('getcwd', 'HAVE_GETCWD', None),
1478 ('stpcpy', 'HAVE_STPCPY', None),
1479 ('strcasecmp', 'HAVE_STRCASECMP', None),
1480 ('strdup', 'HAVE_STRDUP', None),
1481 ('strtoul', 'HAVE_STRTOUL', None),
1482 ('alloca', 'HAVE_ALLOCA', None),
1483 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1484 ('mempcpy', 'HAVE_MEMPCPY', None),
1485 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1486 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1487 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1488 ('setlocale', 'HAVE_SETLOCALE', None),
1489 ('tsearch', 'HAVE_TSEARCH', None),
1490 ('getegid', 'HAVE_GETEGID', None),
1491 ('getgid', 'HAVE_GETGID', None),
1492 ('getuid', 'HAVE_GETUID', None),
1493 ('wcslen', 'HAVE_WCSLEN', None),
1494 ('asprintf', 'HAVE_ASPRINTF', None),
1495 ('wprintf', 'HAVE_WPRINTF', None),
1496 ('snprintf', 'HAVE_SNPRINTF', None),
1497 ('printf', 'HAVE_POSIX_PRINTF', None),
1498 ('fcntl', 'HAVE_FCNTL', None),
1501 ('intmax_t', 'HAVE_INTMAX_T', None),
1502 ('long double', 'HAVE_LONG_DOUBLE', None),
1503 ('long long', 'HAVE_LONG_LONG', None),
1504 ('wchar_t', 'HAVE_WCHAR_T', None),
1505 ('wint_t', 'HAVE_WINT_T', None),
1506 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1507 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1510 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1514 (conf.CheckLC_MESSAGES(),
1516 'Define if your <locale.h> file defines LC_MESSAGES.'
1518 (conf.CheckIconvConst(),
1520 'Define as const if the declaration of iconv() needs const.',
1521 '#define ICONV_CONST',
1522 '#define ICONV_CONST const',
1524 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1525 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1527 "Define to 1 if you have the `intmax_t' type."
1529 (env.has_key('nls') and env['nls'],
1531 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1534 config_post = '#endif'
1537 # these keys are needed in env
1538 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1539 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1540 # USE_ASPELL etc does not go through result
1541 if result.has_key(key):
1542 env[key] = result[key]
1543 env_cache[key] = env[key]
1545 # only a few variables need to be rescanned
1546 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1547 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1548 env[key] = env_cache[key]
1550 print "Processing files in intl..."
1552 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1554 # we need the original C compiler for these files
1555 intlenv['CC'] = C_COMPILER
1556 intlenv['CCFLAGS'] = C_CCFLAGS
1558 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1559 # intl does not use global config.h
1560 intlenv['CPPPATH'] = ['intl'] + extra_inc_paths
1562 intlenv.Append(CCFLAGS = [
1563 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1564 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1565 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1567 '-DENABLE_RELOCATABLE=1',
1569 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1571 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1572 '-Drelocate=libintl_relocate',
1573 '-DDEPENDS_ON_LIBICONV=1',
1578 # libgnuintl.h.in => libintl.h
1579 env.substFile('$TOP_SRCDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1580 env.Command('$TOP_SRCDIR/intl/libgnuintl.h', '$TOP_SRCDIR/intl/libintl.h',
1581 [Copy('$TARGET', '$SOURCE')])
1583 intl = intlenv.StaticLibrary(
1584 target = '$LOCALLIBPATH/included_intl',
1586 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1587 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1588 build_dir = '$BUILDDIR/intl')
1594 # Now, src code under src/
1596 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1603 print "Processing files in src/support..."
1605 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1607 support = env.StaticLibrary(
1608 target = '$LOCALLIBPATH/support',
1609 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1610 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1611 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1613 Alias('support', support)
1620 print "Processing files in src/mathed..."
1621 env['PCH_H'] = '$TOP_SRCDIR/src/mathed/pch.h'
1622 env['PCH_FILE'] = env.PCH(env['PCH_H'])
1624 mathed = env.StaticLibrary(
1625 target = '$LOCALLIBPATH/mathed',
1626 source = env['PCH_FILE'] + utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1628 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1629 build_dir = '$BUILDDIR/common/mathed')
1631 Alias('mathed', mathed)
1638 print "Processing files in src/insets..."
1640 insets = env.StaticLibrary(
1641 target = '$LOCALLIBPATH/insets',
1642 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1644 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1646 Alias('insets', insets)
1653 print "Processing files in src/frontends..."
1655 frontends = env.StaticLibrary(
1656 target = '$LOCALLIBPATH/frontends',
1657 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1658 build_dir = '$BUILDDIR/common/frontends')
1660 Alias('frontends', frontends)
1667 print "Processing files in src/graphics..."
1669 graphics = env.StaticLibrary(
1670 target = '$LOCALLIBPATH/graphics',
1671 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1672 build_dir = '$BUILDDIR/common/graphics')
1674 Alias('graphics', graphics)
1677 if build_controllers:
1679 # src/frontends/controllers
1681 print "Processing files in src/frontends/controllers..."
1683 controllers = env.StaticLibrary(
1684 target = '$LOCALLIBPATH/controllers',
1685 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1686 build_dir = '$BUILDDIR/common/frontends/controllers')
1688 Alias('controllers', controllers)
1692 # src/frontend/qt2/3/4
1694 if build_qt2 or build_qt3 or build_qt4:
1695 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1699 print "Processing files in src/frontends/qt2..."
1702 # disable auto scan to speed up non build time
1703 qt2env['QT_AUTOSCAN'] = 0
1704 qt2env['QT_MOCHPREFIX'] = ''
1709 qt2env.AppendUnique(CPPPATH = [
1711 '$BUILDDIR/common/images',
1712 '$BUILDDIR/common/frontends',
1713 '$BUILDDIR/common/frontends/qt2',
1714 '$BUILDDIR/common/frontends/controllers',
1718 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1721 FileDialog_private.C
1760 QSpellcheckerDialog.C
1762 QTabularCreateDialog.C
1777 # manually moc and uic files for better performance
1778 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1780 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1781 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1783 qt2_uiced_cc_files = []
1784 for x in qt2_uiced_files:
1785 qt2_uiced_cc_files.extend(x[1:])
1787 qt2 = qt2env.StaticLibrary(
1788 target = '$LOCALLIBPATH/qt2',
1789 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1790 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1796 print "Processing files in src/frontends/qt3..."
1799 # disable auto scan to speed up non build time
1800 qt3env['QT_AUTOSCAN'] = 0
1801 qt3env['QT_MOCHPREFIX'] = ''
1806 qt3env.AppendUnique(CPPPATH = [
1808 '$BUILDDIR/common/images',
1809 '$BUILDDIR/common/frontends',
1810 '$BUILDDIR/common/frontends/qt3',
1811 '$BUILDDIR/common/frontends/controllers',
1815 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1818 FileDialog_private.C
1858 QSpellcheckerDialog.C
1860 QTabularCreateDialog.C
1875 # manually moc and uic files for better performance
1876 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1878 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1879 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1881 qt3_uiced_cc_files = []
1882 for x in qt3_uiced_files:
1883 qt3_uiced_cc_files.extend(x[1:])
1885 qt3 = qt3env.StaticLibrary(
1886 target = '$LOCALLIBPATH/qt3',
1887 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1888 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1894 print "Processing files in src/frontends/qt4..."
1897 qt4env['QT_AUTOSCAN'] = 0
1899 # local qt4 toolset from
1900 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1902 # NOTE: I have to patch qt4.py since it does not automatically
1903 # process .C file!!! (add to cxx_suffixes )
1905 qt4env.Tool('qt4', [scons_dir])
1906 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1908 qt4env.AppendUnique(CPPPATH = [
1910 '$BUILDDIR/common/images',
1911 '$BUILDDIR/common/frontends',
1912 '$BUILDDIR/common/frontends/qt4',
1913 '$BUILDDIR/common/frontends/controllers',
1918 # FIXME: replace by something from pkg_config
1919 qt4env.Append(CCFLAGS = [
1921 '-DQT_CLEAN_NAMESPACE',
1929 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1932 FileDialog_private.C
1975 QSpellcheckerDialog.C
1977 QTabularCreateDialog.C
1996 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1997 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1998 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
2001 # moc qt4_moc_files, the moced files are included in the original files
2003 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
2005 qt4 = qt4env.StaticLibrary(
2006 target = '$LOCALLIBPATH/qt4',
2007 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
2008 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
2017 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
2019 print "Processing files in src/client..."
2021 if env['HAVE_FCNTL']:
2022 client = env.Program(
2023 target = '$BUILDDIR/common/client/lyxclient',
2024 LIBS = ['support'] + intl_libs + system_libs +
2025 socket_libs + boost_libraries,
2026 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
2027 build_dir = '$BUILDDIR/common/client')
2029 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
2030 client, [Copy('$TARGET', '$SOURCE')]))
2033 Alias('client', client)
2040 print "Processing files in src/tex2lyx..."
2042 tex2lyx_env = env.Copy()
2043 # the order is important here.
2044 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
2045 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2047 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2048 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2049 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2050 [Copy('$TARGET', '$SOURCE')])
2052 tex2lyx = tex2lyx_env.Program(
2053 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2054 LIBS = ['support'] + boost_libraries + system_libs,
2055 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2056 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2057 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2058 build_dir = '$BUILDDIR/common/tex2lyx')
2060 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2061 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2062 Alias('tex2lyx', tex2lyx)
2069 print "Processing files in src..."
2071 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2073 lyx_post_source = Split('''
2082 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2083 lyx_post_source.append('aspell.C')
2084 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2085 lyx_post_source.append('pspell.C')
2086 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2087 lyx_post_source.append('ispell.C')
2089 # msvc requires at least one source file with main()
2090 # so I exclude main.C from lyxbase
2091 lyxbase_pre = env.StaticLibrary(
2092 target = '$LOCALLIBPATH/lyxbase_pre',
2093 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2094 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2095 'ispell.C', 'Variables.C', 'Sectioning.C'],
2096 include = ['version.C'], build_dir = '$BUILDDIR/common')
2098 lyxbase_post = env.StaticLibrary(
2099 target = '$LOCALLIBPATH/lyxbase_post',
2100 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2102 Alias('lyxbase', lyxbase_pre)
2103 Alias('lyxbase', lyxbase_post)
2108 # Build lyx with given frontend
2111 target = '$BUILDDIR/$frontend/lyx',
2112 source = ['$BUILDDIR/common/main.C'],
2130 # [/path/to/lyx.ext] => lyx-qt3.ext
2131 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2132 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2133 [Copy('$TARGET', '$SOURCE')]))
2137 if build_msvs_projects:
2138 def build_project(target, dir, full_target = None,
2139 src_pattern = lyx_ext, include = [], resource = None, rebuild = True):
2140 ''' build mavs project files
2141 target: alias (correspond to directory name)
2142 dir: source directory or directories (a list)
2143 full_target: full path/filename of the target
2144 src_pattern: glob pattern
2145 include: files to include into source
2146 resource: directory or directories with resource (.ui) files
2147 rebuild: whether or not only rebuild this target
2149 For non-debug-able targets like static libraries, target (alias) is
2150 enough to build the target. For executable targets, msvs need to know
2151 the full path to start debug them.
2153 if resource is not None:
2154 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2155 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2159 cmds = 'faststart=yes rebuild='+target
2161 cmds = 'faststart=yes'
2162 if type(dir) == type([]):
2166 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2167 pattern = src_pattern, include = include,
2168 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2169 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2171 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2173 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2174 pattern = src_pattern, include = include,
2175 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2176 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2178 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2179 if full_target is None:
2180 build_target = target
2182 build_target = full_target
2184 proj = env.MSVSProject(
2185 target = target + env['MSVSPROJECTSUFFIX'],
2187 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2190 buildtarget = build_target,
2194 Alias('msvs_projects', proj)
2196 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2197 src_pattern = '*.cpp')
2199 build_project('intl', 'intl', src_pattern = '*.c')
2201 build_project('support', 'src/support', include=['package.C.in'])
2203 build_project('mathed', 'src/mathed')
2205 build_project('insets', 'src/insets')
2207 build_project('frontends', 'src/frontends')
2209 build_project('graphics', 'src/graphics')
2211 build_project('controllers', 'src/frontends/controllers')
2213 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2215 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2217 build_project('client', 'src/client', rebuild=False,
2218 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2220 build_project('tex2lyx', 'src/tex2lyx', rebuild=False,
2221 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2223 build_project('lyxbase', 'src')
2225 if frontend == 'qt3':
2226 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2227 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2228 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2229 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2231 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2232 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2233 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2234 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2241 print 'Processing files in po...'
2246 # files to translate
2247 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2248 # possibly *only* handle these languages
2250 if env.has_key('languages'):
2251 languages = env.make_list(env['lanauges'])
2252 # use defulat msgfmt
2253 if not env['MSGFMT']:
2254 print 'msgfmt does not exist. Can not process po files'
2257 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2260 for f in transfiles:
2262 fname = os.path.split(f)[1]
2264 country = fname.split('.')[0]
2266 if not languages or country in languages:
2267 gmo_files.extend(env.Transfiles(f))
2270 if 'install' in targets:
2271 # if dest_dir is different from prefix.
2272 if env.has_key('exec_prefix'):
2273 bin_dest_dir = env['exec_prefix']
2275 bin_dest_dir = os.path.join(dest_dir, 'bin')
2277 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2279 share_dest_dir = os.path.join(dest_dir, share_dir)
2280 man_dest_dir = os.path.join(dest_dir, man_dir)
2281 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2282 # create the directory if needed
2283 if not os.path.isdir(dest_dir):
2285 os.makedirs(dest_dir)
2288 if not os.path.isdir(dest_dir):
2289 print 'Can not create directory', dest_dir
2294 # do not install these files
2295 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2296 'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
2298 def install(dest, src):
2299 ''' recusive installation of src to dest '''
2300 # separate file and directory
2301 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2302 dirs = filter(os.path.isdir, src)
2304 env.Install(dest, files)
2308 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2309 glob.glob(os.path.join(dir, '*'))) )
2312 # executables (some of them may be none)
2315 version_suffix = program_suffix
2320 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2321 target = os.path.join(bin_dest_dir, target_name)
2322 env.InstallAs(target, lyx)
2323 Alias('install', target)
2324 # install lyx as lyx-qt3
2325 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2326 target = os.path.join(bin_dest_dir, target_name)
2327 env.InstallAs(target, lyx)
2328 Alias('install', target)
2331 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2332 target = os.path.join(bin_dest_dir, target_name)
2333 env.InstallAs(target, tex2lyx)
2334 Alias('install', target)
2336 # install lyxclient, may not exist
2338 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2339 target = os.path.join(bin_dest_dir, target_name)
2340 env.InstallAs(target, client)
2341 Alias('install', target)
2344 dirs = install(share_dest_dir,
2345 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2346 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2347 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2348 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2350 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2351 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2352 Alias('install', dirs)
2354 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2355 env.subst('$TOP_SRCDIR/lyx.man'))
2356 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2357 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2358 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2359 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2360 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2361 x in ['lyx', 'tex2lyx', 'lyxclient']])
2363 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2364 for gmo in gmo_files:
2365 lan = os.path.split(str(gmo))[1].split('.')[0]
2366 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2367 env.InstallAs(dest_file, gmo)
2368 Alias('install', dest_file)
2372 Alias('all', ['lyx', 'client', 'tex2lyx'])
2375 # save environment settings (for fast_start option)
2376 cache_file = open(env_cache_file, 'w')
2377 cPickle.dump(env_cache, cache_file)