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 # 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'))
546 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
548 if env.has_key('qt_lib_path') and env['qt_lib_path']:
549 qt_lib_path = env.subst('$qt_lib_path')
551 qt_lib_path = env.subst('$QTDIR/lib')
552 env.AppendUnique(LIBPATH = [qt_lib_path])
553 # qt4 seems to be using pkg_config
554 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
556 if env.has_key('qt_inc_path') and env['qt_inc_path']:
557 qt_inc_path = env['qt_inc_path']
558 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
559 qt_inc_path = '$QTDIR/include'
560 # this is the path for cygwin.
561 elif os.path.isdir('/usr/include/' + frontend):
562 qt_inc_path = '/usr/include/$frontend'
564 print "Qt include directory not found. Please specify it using qt_inc_path"
566 # Note that this CPPPATH is for testing only
567 # it will be removed before calling SConscript
568 env['CPPPATH'] = [qt_inc_path]
571 # extra_inc_path and extra_lib_path
574 if env.has_key('extra_inc_path') and env['extra_inc_path']:
575 extra_inc_paths.append(env['extra_inc_path'])
576 if env.has_key('extra_lib_path') and env['extra_lib_path']:
577 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
578 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
579 extra_inc_paths.append(env['extra_inc_path1'])
580 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
581 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
582 if env.has_key('extra_bin_path') and env['extra_bin_path']:
583 # maybe only one of them is needed
584 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
585 env['ENV']['PATH'] += os.pathsep + env['extra_bin_path']
586 # extra_inc_paths will be used later by intlenv etc
587 env.AppendUnique(CPPPATH = extra_inc_paths)
590 #----------------------------------------------------------
592 #----------------------------------------------------------
594 conf = Configure(env,
596 'CheckPkgConfig' : utils.checkPkgConfig,
597 'CheckPackage' : utils.checkPackage,
598 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
599 'CheckSelectArgType' : utils.checkSelectArgType,
600 'CheckBoostLibraries' : utils.checkBoostLibraries,
601 'CheckCommand' : utils.checkCommand,
602 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
603 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
604 'CheckIconvConst' : utils.checkIconvConst,
608 # pkg-config? (if not, we use hard-coded options)
610 if conf.CheckPkgConfig('0.15.0'):
611 env['HAS_PKG_CONFIG'] = True
613 print 'pkg-config >= 0.1.50 is not found'
614 env['HAS_PKG_CONFIG'] = False
615 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
617 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
619 # zlib? This is required. (fast_start assumes the existance of zlib)
621 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
622 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
623 print 'Did not find zdll.lib or zlib.h, exiting!'
629 # qt3 does not use pkg_config
630 if frontend in ['qt2', 'qt3']:
631 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
632 print 'Did not find qt libraries, exiting!'
634 elif frontend == 'qt4':
636 # first: try pkg_config
637 if env['HAS_PKG_CONFIG']:
638 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
639 # FIXME: use pkg_config information?
640 #env['QT4_PKG_CONFIG'] = succ
641 # second: try to link to it
643 # Under linux, I can test the following perfectly
644 # Under windows, lib names need to passed as libXXX4.a ...
645 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
646 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
647 # third: try to look up the path
650 for lib in ['QtCore', 'QtGui']:
651 # windows version has something like QtGui4 ...
652 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
653 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
656 # still can not find it
658 print "Qt4 libraries are found."
660 print 'Did not find qt libraries, exiting!'
663 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
666 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
668 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
669 if os.path.isfile(manifest):
670 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
675 if conf.CheckLib('socket'):
676 socket_libs.append('socket')
677 # nsl is the network services library and provides a
678 # transport-level interface to networking services.
679 if conf.CheckLib('nsl'):
680 socket_libs.append('nsl')
681 env_cache['SOCKET_LIBS'] = socket_libs
683 socket_libs = env_cache['SOCKET_LIBS']
685 # check available boost libs (since lyx1.4 does not use iostream)
687 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
688 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
689 boost_libs.append(lib)
692 # check boost libraries
693 boost_opt = ARGUMENTS.get('boost', 'auto')
694 # check for system boost
695 paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
696 # real libraries (included or system)
699 # here I assume that all libraries are in the same directory
700 for lib in boost_libs:
701 if boost_opt == 'included':
702 boost_libraries.append('included_boost_%s' % lib)
703 env['INCLUDED_BOOST'] = True
704 elif boost_opt == 'auto':
705 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
708 boost_libraries.append('included_boost_%s' % lib)
709 env['INCLUDED_BOOST'] = True
711 boost_libraries.append(res[1])
712 env['INCLUDED_BOOST'] = False
713 boost_libpath = res[0]
714 elif boost_opt == 'system':
715 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
717 print "Can not find system boost libraries"
718 print "Please supply a path through extra_lib_path and try again."
719 print "Or use boost=included to use included boost libraries."
722 boost_libraries.append(res[1])
723 env.AppendUnique(LIBPATH = [res[0]])
724 boost_libpath = res[0]
725 env_cache['BOOST_LIBRARIES'] = boost_libraries
726 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
727 env_cache['BOOST_LIBPATH'] = boost_libpath
729 boost_libraries = env_cache['BOOST_LIBRARIES']
730 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
731 boost_libpath = env_cache['BOOST_LIBPATH']
733 if boost_libpath is not None:
734 env.AppendUnique(LIBPATH = [boost_libpath])
737 env['ENABLE_NLS'] = env['nls']
740 if not env['ENABLE_NLS']:
742 included_gettext = False
744 # check gettext libraries
745 gettext_opt = ARGUMENTS.get('gettext', 'auto')
746 # check for system gettext
748 if gettext_opt in ['auto', 'system']:
749 if conf.CheckLib('intl'):
750 included_gettext = False
754 if gettext_opt == 'system':
755 print "Can not find system gettext library"
756 print "Please supply a path through extra_lib_path and try again."
757 print "Or use gettext=included to use included gettext libraries."
759 # now, auto and succ = false, or gettext=included
761 # we do not need to set LIBPATH now.
762 included_gettext = True
763 intl_libs = ['included_intl']
764 env_cache['INCLUDED_GETTEXT'] = included_gettext
765 env_cache['INTL_LIBS'] = intl_libs
767 included_gettext = env_cache['INCLUDED_GETTEXT']
768 intl_libs = env_cache['INTL_LIBS']
771 # check for msgfmt command
773 env['MSGFMT'] = conf.CheckCommand('msgfmt')
774 env_cache['MSGFMT'] = env['MSGFMT']
776 env['MSGFMT'] = env_cache['MSGFMT']
779 # Customized builders
781 # install customized builders
782 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
785 #----------------------------------------------------------
786 # Generating config.h
787 #----------------------------------------------------------
788 aspell_lib = 'aspell'
789 # assume that we use aspell, aspelld compiled for msvc
790 if platform_name == 'win32' and mode == 'debug' and use_vc:
791 aspell_lib = 'aspelld'
793 # check the existence of config.h
794 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
795 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
796 if not fast_start or not os.path.isfile(boost_config_h) \
797 or not os.path.isfile(config_h):
799 print "Creating %s..." % boost_config_h
801 utils.createConfigFile(conf,
802 config_file = boost_config_h,
803 config_pre = '''/* boost/config.h. Generated by SCons. */
808 * This file is part of LyX, the document processor.
809 * Licence details can be found in the file COPYING.
811 * This is the compilation configuration file for LyX.
812 * It was generated by scon.
813 * You might want to change some of the defaults if something goes wrong
814 * during the compilation.
817 #ifndef _BOOST_CONFIG_H
818 #define _BOOST_CONFIG_H
821 ('ostream', 'HAVE_OSTREAM', 'cxx'),
822 ('locale', 'HAVE_LOCALE', 'cxx'),
823 ('sstream', 'HAVE_SSTREAM', 'cxx'),
824 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
827 (env.has_key('assertions') and env['assertions'],
829 'Define if you want assertions to be enabled in the code'
834 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
835 # define USE_BOOST_FORMAT 1
837 # define USE_BOOST_FORMAT 0
840 #if !defined(ENABLE_ASSERTIONS)
841 # define BOOST_DISABLE_ASSERTS 1
843 #define BOOST_ENABLE_ASSERT_HANDLER 1
845 #define BOOST_DISABLE_THREADS 1
846 #define BOOST_NO_WREGEX 1
847 #define BOOST_NO_WSTRING 1
850 # define BOOST_POSIX 1
853 #define BOOST_ALL_NO_LIB 1
855 #if defined(HAVE_NEWAPIS_H)
856 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
863 print "\nGenerating %s..." % config_h
865 # AIKSAURUS_H_LOCATION
866 if (conf.CheckCXXHeader("Aiksaurus.h")):
867 aik_location = '<Aiksaurus.h>'
868 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
869 aik_location = '<Aiksaurus/Aiksaurus.h>'
873 # determine headers to use
874 spell_opt = ARGUMENTS.get('spell', 'auto')
875 env['USE_ASPELL'] = False
876 env['USE_PSPELL'] = False
877 env['USE_ISPELL'] = False
878 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
879 spell_engine = 'USE_ASPELL'
880 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
881 spell_engine = 'USE_PSPELL'
882 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
883 spell_engine = 'USE_ISPELL'
887 if spell_engine is not None:
888 env[spell_engine] = True
890 if spell_opt == 'auto':
891 print "Warning: Can not locate any spell checker"
892 elif spell_opt != 'no':
893 print "Warning: Can not locate specified spell checker:", spell_opt
896 # check arg types of select function
897 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
901 result = utils.createConfigFile(conf,
902 config_file = config_h,
903 config_pre = '''/* config.h. Generated by SCons. */
908 * This file is part of LyX, the document processor.
909 * Licence details can be found in the file COPYING.
911 * This is the compilation configuration file for LyX.
912 * It was generated by scon.
913 * You might want to change some of the defaults if something goes wrong
914 * during the compilation.
921 ('io.h', 'HAVE_IO_H', 'c'),
922 ('limits.h', 'HAVE_LIMITS_H', 'c'),
923 ('locale.h', 'HAVE_LOCALE_H', 'c'),
924 ('process.h', 'HAVE_PROCESS_H', 'c'),
925 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
926 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
927 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
928 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
929 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
930 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
931 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
932 ('utime.h', 'HAVE_UTIME_H', 'c'),
933 ('direct.h', 'HAVE_DIRECT_H', 'c'),
934 ('istream', 'HAVE_ISTREAM', 'cxx'),
935 ('ios', 'HAVE_IOS', 'cxx'),
938 ('open', 'HAVE_OPEN', None),
939 ('close', 'HAVE_CLOSE', None),
940 ('popen', 'HAVE_POPEN', None),
941 ('pclose', 'HAVE_PCLOSE', None),
942 ('_open', 'HAVE__OPEN', None),
943 ('_close', 'HAVE__CLOSE', None),
944 ('_popen', 'HAVE__POPEN', None),
945 ('_pclose', 'HAVE__PCLOSE', None),
946 ('getpid', 'HAVE_GETPID', None),
947 ('_getpid', 'HAVE__GETPID', None),
948 ('mkdir', 'HAVE_MKDIR', None),
949 ('_mkdir', 'HAVE__MKDIR', None),
950 ('mktemp', 'HAVE_MKTEMP', None),
951 ('mkstemp', 'HAVE_MKSTEMP', None),
952 ('strerror', 'HAVE_STRERROR', None),
953 ('count', 'HAVE_STD_COUNT', '''
958 return std::count(a, a+5, 'l');
961 ('getcwd', 'HAVE_GETCWD', None),
962 ('setenv', 'HAVE_SETENV', None),
963 ('putenv', 'HAVE_PUTENV', None),
964 ('fcntl', 'HAVE_FCNTL', None),
967 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
968 '#include <streambuf>\n#include <istream>')
971 ('gdi32', 'HAVE_LIBGDI32'),
972 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
973 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
976 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
978 'Define is sys/types.h does not have pid_t',
982 (conf.CheckCXXGlobalCstd(),
984 'Define if your C++ compiler puts C library functions in the global namespace'
986 (conf.CheckMkdirOneArg(),
987 'MKDIR_TAKES_ONE_ARG',
988 'Define if mkdir takes only one argument.'
990 (conf.CheckLC_MESSAGES(),
992 'Define if your <locale.h> file defines LC_MESSAGES.'
994 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
997 "Define to 1 if translation of program messages to the user's native anguage is requested.",
999 (env['nls'] and not included_gettext,
1001 'Define to 1 if using system gettext library'
1003 (env.has_key('warnings') and env['warnings'],
1005 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1007 (env.has_key('concept_checks') and env['concept_checks'],
1008 '_GLIBCXX_CONCEPT_CHECKS',
1009 'libstdc++ concept checking'
1011 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1013 'libstdc++ debug mode'
1015 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1016 '_GLIBCXX_DEBUG_PEDANTIC',
1017 'libstdc++ pedantic debug mode'
1019 (os.name != 'nt', 'BOOST_POSIX',
1020 'Indicates to boost which API to use (posix or windows).'
1022 (spell_engine is not None, spell_engine,
1023 'Spell engine to use'
1027 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1029 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1030 'Define to the address where bug reports for this package should be sent.'),
1031 ('#define PACKAGE_NAME "%s"' % package_name,
1032 'Define to the full name of this package.'),
1033 ('#define PACKAGE_STRING "%s"' % package_string,
1034 'Define to the full name and version of this package.'),
1035 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1036 'Define to the one symbol short name of this package.'),
1037 ('#define PACKAGE_VERSION "%s"' % package_version,
1038 'Define to the version of this package.'),
1039 ('#define BOOST_ALL_NO_LIB 1',
1040 'disable automatic linking of boost libraries.'),
1041 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1042 'Packaging method'),
1043 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1044 'Aiksaurus include file'),
1045 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1046 "Define to the type of arg 1 for `select'."),
1047 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1048 "Define to the type of arg 2, 3, 4 for `select'."),
1049 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1050 "Define to the type of arg 5 for `select'."),
1052 config_post = '''/************************************************************
1053 ** You should not need to change anything beyond this point */
1055 #ifndef HAVE_STRERROR
1056 #if defined(__cplusplus)
1059 char * strerror(int n);
1063 #ifndef HAVE_DECL_MKSTEMP
1064 #if defined(__cplusplus)
1071 #include <../boost/config.h>
1077 # these keys are needed in env
1078 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1079 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1080 'ICONV_LIB', 'AIKSAURUS_LIB']:
1081 # USE_ASPELL etc does not go through result
1082 if result.has_key(key):
1083 env[key] = result[key]
1084 env_cache[key] = env[key]
1087 # if nls=yes and gettext=included, create intl/config.h
1088 # intl/libintl.h etc
1090 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1091 if env['nls'] and included_gettext:
1093 print "Creating %s..." % intl_config_h
1095 # create intl/config.h
1096 result = utils.createConfigFile(conf,
1097 config_file = intl_config_h,
1098 config_pre = '''/* intl/config.h. Generated by SCons. */
1103 * This file is part of LyX, the document processor.
1104 * Licence details can be found in the file COPYING.
1106 * This is the compilation configuration file for LyX.
1107 * It was generated by scon.
1108 * You might want to change some of the defaults if something goes wrong
1109 * during the compilation.
1116 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1117 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1118 ('string.h', 'HAVE_STRING_H', 'c'),
1119 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1120 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1121 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1122 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1123 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1124 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1125 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1128 ('getcwd', 'HAVE_GETCWD', None),
1129 ('stpcpy', 'HAVE_STPCPY', None),
1130 ('strcasecmp', 'HAVE_STRCASECMP', None),
1131 ('strdup', 'HAVE_STRDUP', None),
1132 ('strtoul', 'HAVE_STRTOUL', None),
1133 ('alloca', 'HAVE_ALLOCA', None),
1134 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1135 ('mempcpy', 'HAVE_MEMPCPY', None),
1136 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1137 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1138 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1139 ('setlocale', 'HAVE_SETLOCALE', None),
1140 ('tsearch', 'HAVE_TSEARCH', None),
1141 ('getegid', 'HAVE_GETEGID', None),
1142 ('getgid', 'HAVE_GETGID', None),
1143 ('getuid', 'HAVE_GETUID', None),
1144 ('wcslen', 'HAVE_WCSLEN', None),
1145 ('asprintf', 'HAVE_ASPRINTF', None),
1146 ('wprintf', 'HAVE_WPRINTF', None),
1147 ('snprintf', 'HAVE_SNPRINTF', None),
1148 ('printf', 'HAVE_POSIX_PRINTF', None),
1149 ('fcntl', 'HAVE_FCNTL', None),
1152 ('intmax_t', 'HAVE_INTMAX_T', None),
1153 ('long double', 'HAVE_LONG_DOUBLE', None),
1154 ('long long', 'HAVE_LONG_LONG', None),
1155 ('wchar_t', 'HAVE_WCHAR_T', None),
1156 ('wint_t', 'HAVE_WINT_T', None),
1157 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1158 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1161 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1165 (conf.CheckLC_MESSAGES(),
1167 'Define if your <locale.h> file defines LC_MESSAGES.'
1169 (conf.CheckIconvConst(),
1171 'Define as const if the declaration of iconv() needs const.',
1172 '#define ICONV_CONST',
1173 '#define ICONV_CONST const',
1175 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1176 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1178 "Define to 1 if you have the `intmax_t' type."
1180 (env.has_key('nls') and env['nls'],
1182 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1185 config_post = '#endif'
1188 # these keys are needed in env
1189 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1190 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1191 # USE_ASPELL etc does not go through result
1192 if result.has_key(key):
1193 env[key] = result[key]
1194 env_cache[key] = env[key]
1198 # this comes as a big surprise, without this line
1199 # (doing nothing obvious), adding fast_start=yes
1200 # to a build with fast_start=no will result in a rebuild
1201 # Note that the exact header file to check does not matter
1202 conf.CheckCHeader('io.h')
1203 # only a few variables need to be rescanned
1204 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1205 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1206 'ICONV_LIB', 'AIKSAURUS_LIB']:
1207 env[key] = env_cache[key]
1210 if env['nls'] and included_gettext:
1211 # only a few variables need to be rescanned
1212 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1213 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1214 env[key] = env_cache[key]
1216 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1217 if env['nls'] and included_gettext:
1218 # libgnuintl.h.in => libintl.h
1219 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1220 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1221 [Copy('$TARGET', '$SOURCE')])
1224 # Finish auto-configuration
1227 #----------------------------------------------------------
1228 # Now set up our build process accordingly
1229 #----------------------------------------------------------
1234 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1235 # in their respective directory and specialized env.
1237 if frontend in ['qt2', 'qt3']:
1238 # note: env.Tool('qt') my set QT_LIB to qt
1240 frontend_libs = ['qt-mt']
1241 elif frontend == 'qt4':
1242 qt_libs = ['QtCore', 'QtGui']
1243 # set the right lib names
1244 if platform_name == 'win32':
1245 if mode == 'debug' and use_vc:
1246 qt_lib_suffix = 'd4'
1251 qt_lib_suffix = '_debug'
1254 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1256 print "Can not locate qt tools"
1257 print "What I get is "
1258 print " QTDIR: ", env['QTDIR']
1261 if platform_name in ['win32', 'cygwin']:
1262 # the final link step needs stdc++ to succeed under mingw
1263 # FIXME: shouldn't g++ automatically link to stdc++?
1265 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1267 system_libs = ['shlwapi', 'stdc++', 'z']
1268 elif platform_name == 'cygwin' and env['X11']:
1269 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1270 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1276 ('HAVE_ICONV', env['ICONV_LIB']),
1277 ('HAVE_LIBGDI32', 'gdi32'),
1278 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1279 ('USE_ASPELL', aspell_lib),
1280 ('USE_ISPELL', 'ispell'),
1281 ('USE_PSPELL', 'pspell'),
1286 system_libs.append(lib[1])
1289 # Build parameters CPPPATH etc
1292 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1295 # boost: for boost header files
1296 # BUILDDIR/common: for config.h
1297 # TOP_SRCDIR/src: for support/* etc
1299 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$BUILDDIR/common', '$TOP_SRCDIR/src']
1300 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1301 if env['nls'] and included_gettext:
1302 env['CPPPATH'].append('$BUILDDIR/intl')
1304 # QT_INC_PATH is not needed for *every* source file
1305 env['CPPPATH'].remove(qt_inc_path)
1308 # A Link script for cygwin see
1309 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1310 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1313 if platform_name == 'cygwin':
1314 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1315 ld_script = utils.installCygwinLDScript(ld_script_path)
1316 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1317 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1322 # fill in the version info
1323 env['VERSION_INFO'] = '''Configuration
1325 Special build flags: %s
1327 C Compiler flags: %s %s
1329 C++ Compiler LyX flags: %s
1330 C++ Compiler flags: %s %s
1332 Linker user flags: %s
1334 Builing directory: %s
1335 Local library directory: %s
1338 Frontend libraries: %s
1339 System libraries: %s
1340 include search path: %s
1346 ''' % (platform_name,
1347 env.subst('$CCFLAGS'), env.subst('$CC'),
1348 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1349 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1350 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1351 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1352 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1353 str(env['LIBPATH']), str(boost_libraries),
1354 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1355 frontend, packaging_method,
1356 prefix, env['LYX_DIR'])
1358 if frontend in ['qt2', 'qt3', 'qt4']:
1359 env['VERSION_INFO'] += ''' include dir: %s
1362 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1365 print env['VERSION_INFO']
1368 # Mingw command line may be too short for our link usage,
1369 # Here we use a trick from scons wiki
1370 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1372 # I also would like to add logging (commands only) capacity to the
1374 logfile = env.get('logfile', default_log_file)
1375 if logfile != '' or platform_name == 'win32':
1377 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1378 info = '''# This is a log of commands used by scons to build lyx
1382 ''' % (time.asctime(), ' '.join(sys.argv),
1383 env['VERSION_INFO'].replace('\n','\n# ')) )
1388 # -h will print out help info
1389 Help(opts.GenerateHelpText(env))
1391 # save environment settings (for fast_start option)
1392 cache_file = open(env_cache_file, 'w')
1393 cPickle.dump(env_cache, cache_file)
1397 #----------------------------------------------------------
1399 #----------------------------------------------------------
1400 # this has been the source of problems on some platforms...
1401 # I find that I need to supply it with full path name
1402 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1403 # this usage needs further investigation.
1404 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1406 print "Building all targets recursively"
1408 if env.has_key('rebuild'):
1409 rebuild_targets = env['rebuild'].split(',')
1411 rebuild_targets = None
1413 def libExists(libname):
1414 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1415 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1417 targets = BUILD_TARGETS
1418 # msvc need to pass full target name, so I have to look for path/lyx etc
1419 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1420 or 'install' in targets or 'all' in targets
1421 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1422 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1423 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1424 build_mathed = build_lyx or 'mathed' in targets
1425 build_insets = build_lyx or 'insets' in targets
1426 build_frontends = build_lyx or 'frontends' in targets
1427 build_graphics = build_lyx or 'graphics' in targets
1428 build_controllers = build_lyx or 'controllers' in targets
1429 build_client = True in ['client' in x for x in targets] \
1430 or 'install' in targets or 'all' in targets
1431 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1432 or 'install' in targets or 'all' in targets
1433 build_lyxbase = build_lyx or 'lyxbase' in targets
1434 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1435 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1436 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1437 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1438 build_msvs_projects = use_vc and 'msvs_projects' in targets
1441 # now, if rebuild_targets is specified, do not rebuild some targets
1442 rebuild_targets = rebuild_targets
1444 def ifBuildLib(name, libname, old_value):
1445 # explicitly asked to rebuild
1446 if name in rebuild_targets:
1448 # else if not rebuild, and if the library already exists
1449 elif libExists(libname):
1451 # do not change the original value
1454 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1455 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1456 build_support = ifBuildLib('support', 'support', build_support)
1457 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1458 build_insets = ifBuildLib('insets', 'insets', build_insets)
1459 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1460 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1461 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1462 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1463 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1464 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1465 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1467 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1481 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1483 boostenv = env.Copy()
1486 # boost use its own config.h
1487 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1488 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1490 for lib in boost_libs:
1491 print 'Processing files in boost/libs/%s/src...' % lib
1492 boostlib = boostenv.StaticLibrary(
1493 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1494 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1495 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1497 Alias('boost', boostlib)
1504 intlenv = env.Copy()
1506 print "Processing files in intl..."
1508 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1510 # we need the original C compiler for these files
1511 intlenv['CC'] = C_COMPILER
1512 intlenv['CCFLAGS'] = C_CCFLAGS
1514 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1515 # intl does not use global config.h
1516 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1518 intlenv.Append(CCFLAGS = [
1519 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1520 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1521 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1523 '-DENABLE_RELOCATABLE=1',
1525 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1527 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1528 '-Drelocate=libintl_relocate',
1529 '-DDEPENDS_ON_LIBICONV=1',
1534 intl = intlenv.StaticLibrary(
1535 target = '$LOCALLIBPATH/included_intl',
1537 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1538 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1539 build_dir = '$BUILDDIR/intl')
1545 # Now, src code under src/
1547 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1554 print "Processing files in src/support..."
1556 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1558 support = env.StaticLibrary(
1559 target = '$LOCALLIBPATH/support',
1560 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1561 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1562 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1564 Alias('support', support)
1571 print "Processing files in src/mathed..."
1573 mathed = env.StaticLibrary(
1574 target = '$LOCALLIBPATH/mathed',
1575 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1577 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1578 build_dir = '$BUILDDIR/common/mathed')
1580 Alias('mathed', mathed)
1587 print "Processing files in src/insets..."
1589 insets = env.StaticLibrary(
1590 target = '$LOCALLIBPATH/insets',
1591 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1593 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1595 Alias('insets', insets)
1602 print "Processing files in src/frontends..."
1604 frontends = env.StaticLibrary(
1605 target = '$LOCALLIBPATH/frontends',
1606 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1607 build_dir = '$BUILDDIR/common/frontends')
1609 Alias('frontends', frontends)
1616 print "Processing files in src/graphics..."
1618 graphics = env.StaticLibrary(
1619 target = '$LOCALLIBPATH/graphics',
1620 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1621 build_dir = '$BUILDDIR/common/graphics')
1623 Alias('graphics', graphics)
1626 if build_controllers:
1628 # src/frontends/controllers
1630 print "Processing files in src/frontends/controllers..."
1632 controllers = env.StaticLibrary(
1633 target = '$LOCALLIBPATH/controllers',
1634 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1635 build_dir = '$BUILDDIR/common/frontends/controllers')
1637 Alias('controllers', controllers)
1641 # src/frontend/qt2/3/4
1643 if build_qt2 or build_qt3 or build_qt4:
1644 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1648 print "Processing files in src/frontends/qt2..."
1651 # disable auto scan to speed up non build time
1652 qt2env['QT_AUTOSCAN'] = 0
1653 qt2env['QT_MOCHPREFIX'] = ''
1658 qt2env.AppendUnique(CPPPATH = [
1660 '$BUILDDIR/common/images',
1661 '$BUILDDIR/common/frontends',
1662 '$BUILDDIR/common/frontends/qt2',
1663 '$BUILDDIR/common/frontends/controllers',
1667 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1670 FileDialog_private.C
1709 QSpellcheckerDialog.C
1711 QTabularCreateDialog.C
1726 # manually moc and uic files for better performance
1727 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1729 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1730 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1732 qt2_uiced_cc_files = []
1733 for x in qt2_uiced_files:
1734 qt2_uiced_cc_files.extend(x[1:])
1736 qt2 = qt2env.StaticLibrary(
1737 target = '$LOCALLIBPATH/qt2',
1738 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1739 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1745 print "Processing files in src/frontends/qt3..."
1748 # disable auto scan to speed up non build time
1749 qt3env['QT_AUTOSCAN'] = 0
1750 qt3env['QT_MOCHPREFIX'] = ''
1755 qt3env.AppendUnique(CPPPATH = [
1757 '$BUILDDIR/common/images',
1758 '$BUILDDIR/common/frontends',
1759 '$BUILDDIR/common/frontends/qt3',
1760 '$BUILDDIR/common/frontends/controllers',
1764 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1767 FileDialog_private.C
1807 QSpellcheckerDialog.C
1809 QTabularCreateDialog.C
1824 # manually moc and uic files for better performance
1825 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1827 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1828 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1830 qt3_uiced_cc_files = []
1831 for x in qt3_uiced_files:
1832 qt3_uiced_cc_files.extend(x[1:])
1834 qt3 = qt3env.StaticLibrary(
1835 target = '$LOCALLIBPATH/qt3',
1836 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1837 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1843 print "Processing files in src/frontends/qt4..."
1846 qt4env['QT_AUTOSCAN'] = 0
1848 # local qt4 toolset from
1849 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1851 # NOTE: I have to patch qt4.py since it does not automatically
1852 # process .C file!!! (add to cxx_suffixes )
1854 qt4env.Tool('qt4', [scons_dir])
1855 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1857 qt4env.AppendUnique(CPPPATH = [
1859 '$BUILDDIR/common/images',
1860 '$BUILDDIR/common/frontends',
1861 '$BUILDDIR/common/frontends/qt4',
1862 '$BUILDDIR/common/frontends/controllers',
1867 # FIXME: replace by something from pkg_config
1868 qt4env.Append(CCFLAGS = [
1870 '-DQT_CLEAN_NAMESPACE',
1878 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1881 FileDialog_private.C
1924 QSpellcheckerDialog.C
1926 QTabularCreateDialog.C
1945 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1946 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1947 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1950 # moc qt4_moc_files, the moced files are included in the original files
1952 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1954 qt4 = qt4env.StaticLibrary(
1955 target = '$LOCALLIBPATH/qt4',
1956 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1957 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1966 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1968 print "Processing files in src/client..."
1970 if env['HAVE_FCNTL']:
1971 client = env.Program(
1972 target = '$BUILDDIR/common/client/lyxclient',
1973 LIBS = ['support'] + intl_libs + system_libs +
1974 socket_libs + boost_libraries,
1975 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1976 build_dir = '$BUILDDIR/common/client')
1978 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1979 client, [Copy('$TARGET', '$SOURCE')]))
1982 Alias('client', client)
1989 print "Processing files in src/tex2lyx..."
1991 tex2lyx_env = env.Copy()
1993 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1994 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1996 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1997 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1998 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1999 [Copy('$TARGET', '$SOURCE')])
2001 tex2lyx = tex2lyx_env.Program(
2002 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2003 LIBS = ['support'] + boost_libraries + system_libs,
2004 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2005 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2006 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2007 build_dir = '$BUILDDIR/common/tex2lyx')
2009 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2010 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2011 Alias('tex2lyx', tex2lyx)
2018 print "Processing files in src..."
2020 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2022 lyx_post_source = Split('''
2031 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2032 lyx_post_source.append('aspell.C')
2033 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2034 lyx_post_source.append('pspell.C')
2035 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2036 lyx_post_source.append('ispell.C')
2038 # msvc requires at least one source file with main()
2039 # so I exclude main.C from lyxbase
2040 lyxbase_pre = env.StaticLibrary(
2041 target = '$LOCALLIBPATH/lyxbase_pre',
2042 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2043 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2044 'ispell.C', 'Variables.C', 'Sectioning.C'],
2045 include = ['version.C'], build_dir = '$BUILDDIR/common')
2047 lyxbase_post = env.StaticLibrary(
2048 target = '$LOCALLIBPATH/lyxbase_post',
2049 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2051 Alias('lyxbase', lyxbase_pre)
2052 Alias('lyxbase', lyxbase_post)
2057 # Build lyx with given frontend
2060 target = '$BUILDDIR/$frontend/lyx',
2061 source = ['$BUILDDIR/common/main.C'],
2079 # [/path/to/lyx.ext] => lyx-qt3.ext
2080 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2081 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2082 [Copy('$TARGET', '$SOURCE')]))
2086 if build_msvs_projects:
2087 def build_project(target, dir, full_target = None,
2088 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2089 ''' build mavs project files
2090 target: alias (correspond to directory name)
2091 dir: source directory or directories (a list)
2092 full_target: full path/filename of the target
2093 src_pattern: glob pattern
2094 include: files to include into source
2095 resource: directory or directories with resource (.ui) files
2096 rebuildTargetOnly: whether or not only rebuild this target
2098 For non-debug-able targets like static libraries, target (alias) is
2099 enough to build the target. For executable targets, msvs need to know
2100 the full path to start debug them.
2102 if resource is not None:
2103 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2104 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2107 if rebuildTargetOnly:
2108 cmds = 'faststart=yes rebuild='+target
2110 cmds = 'faststart=yes'
2111 if type(dir) == type([]):
2115 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2116 pattern = src_pattern, include = include,
2117 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2118 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2120 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2122 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2123 pattern = src_pattern, include = include,
2124 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2125 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2127 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2128 if full_target is None:
2129 build_target = target
2131 build_target = full_target
2133 proj = env.MSVSProject(
2134 target = target + env['MSVSPROJECTSUFFIX'],
2136 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2139 buildtarget = build_target,
2143 Alias('msvs_projects', proj)
2145 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2146 src_pattern = '*.cpp')
2148 build_project('intl', 'intl', src_pattern = '*.c')
2150 build_project('support', 'src/support', include=['package.C.in'])
2152 build_project('mathed', 'src/mathed')
2154 build_project('insets', 'src/insets')
2156 build_project('frontends', 'src/frontends')
2158 build_project('graphics', 'src/graphics')
2160 build_project('controllers', 'src/frontends/controllers')
2162 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2164 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2166 build_project('client', 'src/client', rebuildTargetOnly = False,
2167 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2169 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2170 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2172 build_project('lyxbase', 'src')
2174 if frontend == 'qt3':
2175 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2176 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2177 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2178 rebuildTargetOnly = False,
2179 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2181 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2182 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2183 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2184 rebuildTargetOnly = False,
2185 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2192 print 'Processing files in po...'
2197 # files to translate
2198 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2199 # possibly *only* handle these languages
2201 if env.has_key('languages'):
2202 languages = env.make_list(env['lanauges'])
2203 # use defulat msgfmt
2204 if not env['MSGFMT']:
2205 print 'msgfmt does not exist. Can not process po files'
2208 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2211 for f in transfiles:
2213 fname = os.path.split(f)[1]
2215 country = fname.split('.')[0]
2217 if not languages or country in languages:
2218 gmo_files.extend(env.Transfiles(f))
2221 if 'install' in targets:
2223 # install to DESTDIR or prefix
2224 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2225 # if dest_dir is different from prefix.
2226 if env.has_key('exec_prefix'):
2227 bin_dest_dir = Dir(env['exec_prefix']).abspath
2229 bin_dest_dir = os.path.join(dest_dir, 'bin')
2231 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2233 share_dest_dir = os.path.join(dest_dir, share_dir)
2234 man_dest_dir = os.path.join(dest_dir, man_dir)
2235 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2236 # create the directory if needed
2237 if not os.path.isdir(dest_dir):
2239 os.makedirs(dest_dir)
2242 if not os.path.isdir(dest_dir):
2243 print 'Can not create directory', dest_dir
2248 # do not install these files
2249 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2250 'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
2252 def install(dest, src):
2253 ''' recusive installation of src to dest '''
2254 # separate file and directory
2255 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2256 dirs = filter(os.path.isdir, src)
2258 env.Install(dest, files)
2262 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2263 glob.glob(os.path.join(dir, '*'))) )
2266 # executables (some of them may be none)
2269 version_suffix = program_suffix
2274 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2275 target = os.path.join(bin_dest_dir, target_name)
2276 env.InstallAs(target, lyx)
2277 Alias('install', target)
2278 # install lyx as lyx-qt3
2279 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2280 target = os.path.join(bin_dest_dir, target_name)
2281 env.InstallAs(target, lyx)
2282 Alias('install', target)
2285 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2286 target = os.path.join(bin_dest_dir, target_name)
2287 env.InstallAs(target, tex2lyx)
2288 Alias('install', target)
2290 # install lyxclient, may not exist
2292 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2293 target = os.path.join(bin_dest_dir, target_name)
2294 env.InstallAs(target, client)
2295 Alias('install', target)
2298 dirs = install(share_dest_dir,
2299 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2300 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2301 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2302 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2304 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2305 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2306 Alias('install', dirs)
2308 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2309 env.subst('$TOP_SRCDIR/lyx.man'))
2310 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2311 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2312 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2313 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2314 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2315 x in ['lyx', 'tex2lyx', 'lyxclient']])
2317 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2318 for gmo in gmo_files:
2319 lan = os.path.split(str(gmo))[1].split('.')[0]
2320 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2321 env.InstallAs(dest_file, gmo)
2322 Alias('install', dest_file)
2326 Alias('all', ['lyx', 'client', 'tex2lyx'])