1 # vi:filetype=python:expandtab:tabstop=4:shiftwidth=4
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
9 # Full author contact details are available in file CREDITS.
11 # This is a scons based building system for lyx, please refer
12 # to INSTALL.scons for detailed instructions.
15 import os, sys, copy, cPickle, glob
17 # scons_utils.py defines a few utility function
18 sys.path.append('config')
19 import scons_utils as utils
21 #----------------------------------------------------------
22 # Required runtime environment
23 #----------------------------------------------------------
25 # scons asks for 1.5.2, lyx requires 2.3
26 EnsurePythonVersion(2, 3)
27 # Please use at least 0.96.91 (not 0.96.1)
28 EnsureSConsVersion(0, 96)
30 # determine where I am ...
32 # called as 'cd development/scons; scons'
33 if os.path.isfile('SConstruct'):
36 # called as 'scons -f development/scons/SConstruct'
39 scons_dir = 'development/scons'
42 #----------------------------------------------------------
44 #----------------------------------------------------------
46 # some global settings
48 # detect version of lyx
49 # only 1.4.x has frontends/qt2
50 if os.path.isdir(os.path.join(top_src_dir, 'src', 'frontends', 'qt2')):
51 package_version = '1.4.2svn'
53 package_version = '1.5.0svn'
56 default_build_mode = 'debug'
60 package_bugreport = 'lyx-devel@lists.lyx.org'
62 package_tarname = 'lyx'
63 package_string = '%s %s' % (package_name, package_version)
65 # various cache/log files
66 default_log_file = 'scons_lyx.log'
67 env_cache_file = 'env.cache'
70 #----------------------------------------------------------
71 # platform dependent settings
72 #----------------------------------------------------------
75 platform_name = 'win32'
76 default_frontend = 'qt4'
77 default_prefix = 'c:/program files/lyx'
78 default_with_x = False
79 default_packaging_method = 'windows'
80 elif os.name == 'posix' and sys.platform != 'cygwin':
81 platform_name = sys.platform
82 default_frontend = 'qt3'
83 default_prefix = '/usr/local'
85 default_packaging_method = 'posix'
86 elif os.name == 'posix' and sys.platform == 'cygwin':
87 platform_name = 'cygwin'
88 default_frontend = 'qt3'
89 default_prefix = '/usr/local'
91 default_packaging_method = 'posix'
92 elif os.name == 'darwin':
93 platform_name = 'macosx'
94 default_frontend = 'qt3'
95 # FIXME: macOSX default prefix?
97 default_with_x = False
98 default_packaging_method = 'macosx'
99 else: # unsupported system, assume posix behavior
100 platform_name = 'others'
101 default_frontend = 'qt3'
103 default_with_x = True
104 default_packaging_method = 'posix'
107 #---------------------------------------------------------
109 #----------------------------------------------------------
111 # You can set perminant default values in config.py
112 if os.path.isfile('config.py'):
113 print "Getting options from config.py..."
114 print open('config.py').read()
116 opts = Options(['config.py'])
119 EnumOption('frontend', 'Main GUI', default_frontend,
120 allowed_values = ('xform', 'qt2', 'qt3', 'qt4', 'gtk') ),
121 # debug or release build
122 EnumOption('mode', 'Building method', default_build_mode,
123 allowed_values = ('debug', 'release') ),
126 'Use included, system boost library, or try sytem boost first.',
127 'auto', allowed_values = (
128 'auto', # detect boost, if not found, use included
129 'included', # always use included boost
130 'system', # always use system boost, fail if can not find
133 EnumOption('gettext',
134 'Use included, system gettext library, or try sytem gettext first',
135 'auto', allowed_values = (
136 'auto', # detect gettext, if not found, use included
137 'included', # always use included gettext
138 'system', # always use system gettext, fail if can not find
141 EnumOption('spell', 'Choose spell checker to use.', 'auto',
142 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
144 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
145 allowed_values = ('windows', 'posix', 'macosx')),
147 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
148 # No precompiled header support (too troublesome to make it work for msvc)
149 # BoolOption('pch', 'Whether or not use pch', False),
150 # enable assertion, (config.h has ENABLE_ASSERTIOS
151 BoolOption('assertions', 'Use assertions', True),
152 # enable warning, (config.h has WITH_WARNINGS)
153 # default to False since MSVC does not have #warning
154 BoolOption('warnings', 'Use warnings', False),
155 # config.h define _GLIBCXX_CONCEPT_CHECKS
156 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
157 BoolOption('concept_checks', 'Enable concept checks', True),
159 BoolOption('nls', 'Whether or not use native language support', True),
161 BoolOption('profiling', 'Whether or not enable profiling', False),
162 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
163 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
165 BoolOption('X11', 'Use x11 windows system', default_with_x),
166 # use MS VC++ to build lyx
167 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
169 PathOption('qt_dir', 'Path to qt directory', None),
171 PathOption('qt_include_path', 'Path to qt include directory', None),
173 PathOption('qt_lib_path', 'Path to qt library directory', None),
174 # build directory, will use $mode if not set
175 PathOption('build_dir', 'Build directory', None),
176 # extra include and libpath
177 PathOption('extra_inc_path', 'Extra include path', None),
179 PathOption('extra_lib_path', 'Extra library path', None),
181 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
183 PathOption('extra_inc_path1', 'Extra include path', None),
185 PathOption('extra_lib_path1', 'Extra library path', None),
186 # rebuild only specifed, comma separated targets
187 ('rebuild', 'rebuild only specifed, comma separated targets', None),
188 # can be set to a non-existing directory
189 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
191 ('version_suffix', 'install lyx as lyx-suffix', None),
192 # how to load options
193 ('load_option', '''load option from previous scons run. option can be
194 yes (default): load all options
195 no: do not load any option
196 opt1,opt2: load specified options
197 -opt1,opt2: load all options other than specified ones''', 'yes'),
199 ('optimization', 'optimization CCFLAGS option.', None),
201 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
203 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
204 # provided for backward compatibility
205 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
206 # environment variable can be set as options.
207 ('DESTDIR', 'install to DESTDIR', None),
208 ('CC', 'replace default $CC', None),
209 ('LINK', 'replace default $LINK', None),
210 ('CPP', 'replace default $CPP', None),
211 ('CXX', 'replace default $CXX', None),
212 ('CXXCPP', 'replace default $CXXCPP', None),
213 ('CCFLAGS', 'replace default $CCFLAGS', None),
214 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
215 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
218 # copied from SCons/Options/BoolOption.py
219 # We need to use them before a boolean ARGUMENTS option is available
221 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
222 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
224 # whether or not use current config.h, and cached tests
226 # if fast_start=yes (default), load variables from env_cache_file
227 if (not ARGUMENTS.has_key('fast_start') or \
228 ARGUMENTS['fast_start'] in true_strings) \
229 and os.path.isfile(env_cache_file):
231 cache_file = open(env_cache_file)
232 env_cache = cPickle.load(cache_file)
234 print '------------ fast_start mode --------------------'
235 print ' Use cached test results and current config.h'
236 print ' use fast_start=no to override'
242 # if load_option=yes (default), load saved comand line options
244 # This option can take value yes/no/opt1,opt2/-opt1,opt2
245 # and tries to be clever in choosing options to load
246 if (not ARGUMENTS.has_key('load_option') or \
247 ARGUMENTS['load_option'] not in false_strings) \
248 and os.path.isfile(env_cache_file):
249 cache_file = open(env_cache_file)
250 opt_cache = cPickle.load(cache_file)['arg_cache']
252 # import cached options, but we should ignore qt_dir when frontend changes
253 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
254 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
255 and opt_cache.has_key('qt_dir'):
256 opt_cache.pop('qt_dir')
257 # some options will require full rebuild
258 # these are in general things that will change config.h
259 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
260 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
261 ARGUMENTS[arg] != opt_cache[arg]):
263 print " ** fast_start is disabled because of the change of option", arg
266 # and we do not cache some options
267 for arg in ['fast_start', 'load_option']:
268 if opt_cache.has_key(arg):
270 # now, if load_option=opt1,opt2 or -opt1,opt2
271 if ARGUMENTS.has_key('load_option') and \
272 ARGUMENTS['load_option'] not in true_strings + false_strings:
273 # if -opt1,opt2 is specified, do not load these options
274 if ARGUMENTS['load_option'][0] == '-':
275 for arg in ARGUMENTS['load_option'][1:].split(','):
276 if opt_cache.has_key(arg):
278 # if opt1,opt2 is specified, only load specified options
280 args = ARGUMENTS['load_option'].split(',')
281 for arg in opt_cache.keys():
284 # now restore options as if entered from command line
285 for key in opt_cache.keys():
286 if not ARGUMENTS.has_key(key):
287 ARGUMENTS[key] = opt_cache[key]
288 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
292 env_cache['arg_cache'] = ARGUMENTS
295 #---------------------------------------------------------
296 # Setting up environment
297 #---------------------------------------------------------
299 # I do not really like ENV=os.environ, but you may add it
300 # here if you experience some environment related problem
301 env = Environment(options = opts)
303 # set individual variables since I do not really like ENV = os.environ
304 env['ENV']['PATH'] = os.environ.get('PATH')
305 env['ENV']['HOME'] = os.environ.get('HOME')
306 # these are defined for MSVC
307 env['ENV']['LIB'] = os.environ.get('LIB')
308 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
310 # for simplicity, use var instead of env[var]
311 frontend = env['frontend']
312 prefix = env['prefix']
315 if platform_name == 'win32':
316 if env.has_key('use_vc'):
317 use_vc = env['use_vc']
318 if WhereIs('cl.exe') is None:
319 print "cl.exe is not found. Are you using the MSVC environment?"
321 elif WhereIs('cl.exe') is not None:
328 # lyx will be built to $build/build_dir so it is possible
329 # to build multiple build_dirs using the same source
330 # $mode can be debug or release
331 if env.has_key('build_dir') and env['build_dir'] is not None:
332 env['BUILDDIR'] = env['build_dir']
334 # Determine the name of the build $mode
335 env['BUILDDIR'] = '#' + mode
337 # all built libraries will go to build_dir/libs
338 # (This is different from the make file approach)
339 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
340 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
343 # Here is a summary of variables defined in env
345 # 2. undefined options with a non-None default value
346 # 3. compiler commands and flags like CCFLAGS.
347 # MSGFMT used to process po files
348 # 4. Variables that will be used to replace variables in some_file.in
349 # src/support/package.C.in:
350 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
351 # lib/lyx2lyx/lyx2lyx_version.py.in
354 # PACKAGE_VERSION, VERSION_INFO
355 # src/frontends/xforms/lyx_xpm.h.in
357 # src/frontends/xforms/lyx_forms.h.in
360 # full path name is used to build msvs project files
361 # and to replace TOP_SRCDIR in package.C
362 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
363 # needed by src/version.C.in => src/version.C
364 env['PACKAGE_VERSION'] = package_version
366 # determine share_dir etc
367 packaging_method = env.get('packaging')
368 if packaging_method == 'windows':
369 share_dir = 'Resources'
370 man_dir = 'Resources/man/man1'
371 locale_dir = 'Resources/locale'
372 default_prefix = 'c:/program files/lyx'
374 share_dir = 'share/lyx'
376 locale_dir = 'share/locale'
377 default_prefix = '/usr/local/'
379 # install to default_prefix by default
380 # program suffix: can be yes, or a string
381 if env.has_key('version_suffix'):
382 if env['version_suffix'] in true_strings:
383 program_suffix = package_version
384 elif env['version_suffix'] in false_strings:
387 program_suffix = env['version_suffix']
390 # used by package.C.in
391 env['PROGRAM_SUFFIX'] = program_suffix
393 # whether or not add suffix to file and directory names
394 add_suffix = packaging_method != 'windows'
395 # LYX_DIR are different (used in package.C.in)
397 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
399 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
400 # we need absolute path for package.C
401 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
404 #---------------------------------------------------------
405 # Setting building environment (Tools, compiler flags etc)
406 #---------------------------------------------------------
408 # Since Tool('mingw') will reset CCFLAGS etc, this should be
409 # done before getEnvVariable
410 if platform_name == 'win32':
416 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
418 # we differentiate between hard-coded options and default options
419 # hard-coded options are required and will always be there
420 # default options can be replaced by enviromental variables or command line options
421 CCFLAGS_required = []
422 LINKFLAGS_required = []
425 # under windows, scons is confused by .C/.c and uses gcc instead of
426 # g++. I am forcing the use of g++ here. This is expected to change
427 # after lyx renames all .C files to .cpp
429 # save the old c compiler and CCFLAGS (used by libintl)
430 C_COMPILER = env.subst('$CC')
431 C_CCFLAGS = env.subst('$CCFLAGS').split()
432 # if we use ms vc, the commands are fine (cl.exe and link.exe)
434 # /TP treat all source code as C++
435 # C4819: The file contains a character that cannot be represented
436 # in the current code page (number)
437 # C4996: foo was decleared deprecated
438 CCFLAGS_required.extend(['/TP', '/EHsc'])
439 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
441 if env.has_key('CXX') and env['CXX']:
442 env['CC'] = env.subst('$CXX')
443 env['LINK'] = env.subst('$CXX')
448 # for debug/release mode
449 if env.has_key('optimization') and env['optimization'] is not None:
450 # if user supplies optimization flags, use it anyway
451 CCFLAGS_required.extend(env['optimization'].split())
452 # and do not use default
453 set_default_optimization_flags = False
455 set_default_optimization_flags = True
459 CCFLAGS_required.append('/Zi')
460 LINKFLAGS_required.extend(['/debug', '/map'])
462 CCFLAGS_required.append('-g')
463 CCFLAGS_default.append('-O')
464 elif mode == 'release' and set_default_optimization_flags:
466 CCFLAGS_default.append('/O2')
468 CCFLAGS_default.append('-O2')
470 # msvc uses separate tools for profiling
471 if env.has_key('profiling') and env['profiling']:
473 print 'Visual C++ does not use profiling options'
475 CCFLAGS_required.append('-pg')
476 LINKFLAGS_required.append('-pg')
478 if env.has_key('warnings') and env['warnings']:
480 CCFLAGS_default.append('/W2')
482 # Note: autotools detect gxx version and pass -W for 3.x
483 # and -Wextra for other versions of gcc
484 CCFLAGS_default.append('-Wall')
486 # Now, set the variables as follows:
487 # 1. if command line option exists: replace default
488 # 2. then if s envronment variable exists: replace default
489 # 3. set variable to required + default
490 def setEnvVariable(env, name, required = None, default = None, split = True):
491 ''' env: environment to set variable
493 required: hardcoded options
494 default: default options that can be replaced by command line or
495 environment variables
496 split: whether or not split obtained variable like '-02 -g'
498 # first try command line argument (override environment settings)
499 if ARGUMENTS.has_key(name):
500 default = ARGUMENTS[name]
502 default = default.split()
503 # then use environment default
504 elif os.environ.has_key(name):
505 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
506 default = os.environ[name]
508 default = default.split()
510 if required is not None:
512 if default is not None:
513 if env.has_key(name) and env[name] != default:
518 setEnvVariable(env, 'DESTDIR', split=False)
519 setEnvVariable(env, 'CC')
520 setEnvVariable(env, 'LINK')
521 setEnvVariable(env, 'CPP')
522 setEnvVariable(env, 'CXX')
523 setEnvVariable(env, 'CXXCPP')
524 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
525 setEnvVariable(env, 'CXXFLAGS')
526 setEnvVariable(env, 'CPPFLAGS')
527 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
529 # if DESTDIR is not set...
530 if env.has_key('dest_dir'):
531 print "This option is obsolete. Please use DESTDIR instead."
532 env['DESTDIR'] = env['dest_dir']
535 #---------------------------------------------------------
536 # Frontend related variables (QTDIR etc)
537 #---------------------------------------------------------
539 if env.has_key('qt_dir') and env['qt_dir']:
540 env['QTDIR'] = env['qt_dir']
541 # add path to the qt tools
542 env.AppendUnique(LIBPATH = [os.path.join(env['qt_dir'], 'lib')])
543 # set environment so that moc etc can be found even if its path is not set properly
544 env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
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')
550 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
551 qt_lib_path = env.subst('$QTDIR/lib')
552 # this is the path for cygwin.
553 elif os.path.idsir(os.path.join('/usr/lib/', frontend, 'lib')):
554 qt_lib_path = env.subst('/usr/lib/$frontend/lib')
556 print "Qt library directory is not found. Please specify it using qt_lib_path"
558 env.AppendUnique(LIBPATH = [qt_lib_path])
559 # qt4 seems to be using pkg_config
560 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
562 if env.has_key('qt_inc_path') and env['qt_inc_path']:
563 qt_inc_path = env['qt_inc_path']
564 elif os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
565 qt_inc_path = '$QTDIR/include'
566 # this is the path for cygwin.
567 elif os.path.isdir('/usr/include/' + frontend):
568 qt_inc_path = '/usr/include/$frontend'
570 print "Qt include directory not found. Please specify it using qt_inc_path"
572 # Note that this CPPPATH is for testing only
573 # it will be removed before calling SConscript
574 env['CPPPATH'] = [qt_inc_path]
577 # extra_inc_path and extra_lib_path
580 if env.has_key('extra_inc_path') and env['extra_inc_path']:
581 extra_inc_paths.append(env['extra_inc_path'])
582 if env.has_key('extra_lib_path') and env['extra_lib_path']:
583 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
584 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
585 extra_inc_paths.append(env['extra_inc_path1'])
586 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
587 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
588 if env.has_key('extra_bin_path') and env['extra_bin_path']:
589 # maybe only one of them is needed
590 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
591 env['ENV']['PATH'] += os.pathsep + env['extra_bin_path']
592 # extra_inc_paths will be used later by intlenv etc
593 env.AppendUnique(CPPPATH = extra_inc_paths)
596 #----------------------------------------------------------
598 #----------------------------------------------------------
600 conf = Configure(env,
602 'CheckPkgConfig' : utils.checkPkgConfig,
603 'CheckPackage' : utils.checkPackage,
604 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
605 'CheckSelectArgType' : utils.checkSelectArgType,
606 'CheckBoostLibraries' : utils.checkBoostLibraries,
607 'CheckCommand' : utils.checkCommand,
608 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
609 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
610 'CheckIconvConst' : utils.checkIconvConst,
614 # pkg-config? (if not, we use hard-coded options)
616 if conf.CheckPkgConfig('0.15.0'):
617 env['HAS_PKG_CONFIG'] = True
619 print 'pkg-config >= 0.1.50 is not found'
620 env['HAS_PKG_CONFIG'] = False
621 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
623 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
625 # zlib? This is required. (fast_start assumes the existance of zlib)
627 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
628 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
629 print 'Did not find zdll.lib or zlib.h, exiting!'
635 # qt3 does not use pkg_config
636 if frontend in ['qt2', 'qt3']:
637 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
638 print 'Did not find qt libraries, exiting!'
640 elif frontend == 'qt4':
642 # first: try pkg_config
643 if env['HAS_PKG_CONFIG']:
644 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
645 # FIXME: use pkg_config information?
646 #env['QT4_PKG_CONFIG'] = succ
647 # second: try to link to it
649 # Under linux, I can test the following perfectly
650 # Under windows, lib names need to passed as libXXX4.a ...
651 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
652 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
653 # third: try to look up the path
656 for lib in ['QtCore', 'QtGui']:
657 # windows version has something like QtGui4 ...
658 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
659 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
662 # still can not find it
664 print "Qt4 libraries are found."
666 print 'Did not find qt libraries, exiting!'
669 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
672 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
674 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
675 if os.path.isfile(manifest):
676 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
681 if conf.CheckLib('socket'):
682 socket_libs.append('socket')
683 # nsl is the network services library and provides a
684 # transport-level interface to networking services.
685 if conf.CheckLib('nsl'):
686 socket_libs.append('nsl')
687 env_cache['SOCKET_LIBS'] = socket_libs
689 socket_libs = env_cache['SOCKET_LIBS']
691 # check available boost libs (since lyx1.4 does not use iostream)
693 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
694 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
695 boost_libs.append(lib)
698 # check boost libraries
699 boost_opt = ARGUMENTS.get('boost', 'auto')
700 # check for system boost
701 paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
702 # real libraries (included or system)
705 # here I assume that all libraries are in the same directory
706 for lib in boost_libs:
707 if boost_opt == 'included':
708 boost_libraries.append('included_boost_%s' % lib)
709 env['INCLUDED_BOOST'] = True
710 elif boost_opt == 'auto':
711 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
714 boost_libraries.append('included_boost_%s' % lib)
715 env['INCLUDED_BOOST'] = True
717 boost_libraries.append(res[1])
718 env['INCLUDED_BOOST'] = False
719 boost_libpath = res[0]
720 elif boost_opt == 'system':
721 res = conf.CheckBoostLibraries('boost_%s' % lib , paths)
723 print "Can not find system boost libraries"
724 print "Please supply a path through extra_lib_path and try again."
725 print "Or use boost=included to use included boost libraries."
728 boost_libraries.append(res[1])
729 env.AppendUnique(LIBPATH = [res[0]])
730 boost_libpath = res[0]
731 env_cache['BOOST_LIBRARIES'] = boost_libraries
732 env_cache['INCLUDED_BOOST'] = env['INCLUDED_BOOST']
733 env_cache['BOOST_LIBPATH'] = boost_libpath
735 boost_libraries = env_cache['BOOST_LIBRARIES']
736 env['INCLUDED_BOOST'] = env_cache['INCLUDED_BOOST']
737 boost_libpath = env_cache['BOOST_LIBPATH']
739 if boost_libpath is not None:
740 env.AppendUnique(LIBPATH = [boost_libpath])
743 env['ENABLE_NLS'] = env['nls']
746 if not env['ENABLE_NLS']:
748 included_gettext = False
750 # check gettext libraries
751 gettext_opt = ARGUMENTS.get('gettext', 'auto')
752 # check for system gettext
754 if gettext_opt in ['auto', 'system']:
755 if conf.CheckLib('intl'):
756 included_gettext = False
760 if gettext_opt == 'system':
761 print "Can not find system gettext library"
762 print "Please supply a path through extra_lib_path and try again."
763 print "Or use gettext=included to use included gettext libraries."
765 # now, auto and succ = false, or gettext=included
767 # we do not need to set LIBPATH now.
768 included_gettext = True
769 intl_libs = ['included_intl']
770 env_cache['INCLUDED_GETTEXT'] = included_gettext
771 env_cache['INTL_LIBS'] = intl_libs
773 included_gettext = env_cache['INCLUDED_GETTEXT']
774 intl_libs = env_cache['INTL_LIBS']
777 # check for msgfmt command
779 env['MSGFMT'] = conf.CheckCommand('msgfmt')
780 env_cache['MSGFMT'] = env['MSGFMT']
782 env['MSGFMT'] = env_cache['MSGFMT']
785 # Customized builders
787 # install customized builders
788 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
791 #----------------------------------------------------------
792 # Generating config.h
793 #----------------------------------------------------------
794 aspell_lib = 'aspell'
795 # assume that we use aspell, aspelld compiled for msvc
796 if platform_name == 'win32' and mode == 'debug' and use_vc:
797 aspell_lib = 'aspelld'
799 # check the existence of config.h
800 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
801 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
802 if not fast_start or not os.path.isfile(boost_config_h) \
803 or not os.path.isfile(config_h):
805 print "Creating %s..." % boost_config_h
807 utils.createConfigFile(conf,
808 config_file = boost_config_h,
809 config_pre = '''/* boost/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.
823 #ifndef _BOOST_CONFIG_H
824 #define _BOOST_CONFIG_H
827 ('ostream', 'HAVE_OSTREAM', 'cxx'),
828 ('locale', 'HAVE_LOCALE', 'cxx'),
829 ('sstream', 'HAVE_SSTREAM', 'cxx'),
830 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
833 (env.has_key('assertions') and env['assertions'],
835 'Define if you want assertions to be enabled in the code'
840 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
841 # define USE_BOOST_FORMAT 1
843 # define USE_BOOST_FORMAT 0
846 #if !defined(ENABLE_ASSERTIONS)
847 # define BOOST_DISABLE_ASSERTS 1
849 #define BOOST_ENABLE_ASSERT_HANDLER 1
851 #define BOOST_DISABLE_THREADS 1
852 #define BOOST_NO_WREGEX 1
853 #define BOOST_NO_WSTRING 1
856 # define BOOST_POSIX 1
859 #define BOOST_ALL_NO_LIB 1
861 #if defined(HAVE_NEWAPIS_H)
862 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
869 print "\nGenerating %s..." % config_h
871 # AIKSAURUS_H_LOCATION
872 if (conf.CheckCXXHeader("Aiksaurus.h")):
873 aik_location = '<Aiksaurus.h>'
874 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
875 aik_location = '<Aiksaurus/Aiksaurus.h>'
879 # determine headers to use
880 spell_opt = ARGUMENTS.get('spell', 'auto')
881 env['USE_ASPELL'] = False
882 env['USE_PSPELL'] = False
883 env['USE_ISPELL'] = False
884 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
885 spell_engine = 'USE_ASPELL'
886 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
887 spell_engine = 'USE_PSPELL'
888 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
889 spell_engine = 'USE_ISPELL'
893 if spell_engine is not None:
894 env[spell_engine] = True
896 if spell_opt == 'auto':
897 print "Warning: Can not locate any spell checker"
898 elif spell_opt != 'no':
899 print "Warning: Can not locate specified spell checker:", spell_opt
902 # check arg types of select function
903 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
907 result = utils.createConfigFile(conf,
908 config_file = config_h,
909 config_pre = '''/* config.h. Generated by SCons. */
914 * This file is part of LyX, the document processor.
915 * Licence details can be found in the file COPYING.
917 * This is the compilation configuration file for LyX.
918 * It was generated by scon.
919 * You might want to change some of the defaults if something goes wrong
920 * during the compilation.
927 ('io.h', 'HAVE_IO_H', 'c'),
928 ('limits.h', 'HAVE_LIMITS_H', 'c'),
929 ('locale.h', 'HAVE_LOCALE_H', 'c'),
930 ('process.h', 'HAVE_PROCESS_H', 'c'),
931 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
932 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
933 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
934 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
935 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
936 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
937 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
938 ('utime.h', 'HAVE_UTIME_H', 'c'),
939 ('direct.h', 'HAVE_DIRECT_H', 'c'),
940 ('istream', 'HAVE_ISTREAM', 'cxx'),
941 ('ios', 'HAVE_IOS', 'cxx'),
944 ('open', 'HAVE_OPEN', None),
945 ('close', 'HAVE_CLOSE', None),
946 ('popen', 'HAVE_POPEN', None),
947 ('pclose', 'HAVE_PCLOSE', None),
948 ('_open', 'HAVE__OPEN', None),
949 ('_close', 'HAVE__CLOSE', None),
950 ('_popen', 'HAVE__POPEN', None),
951 ('_pclose', 'HAVE__PCLOSE', None),
952 ('getpid', 'HAVE_GETPID', None),
953 ('_getpid', 'HAVE__GETPID', None),
954 ('mkdir', 'HAVE_MKDIR', None),
955 ('_mkdir', 'HAVE__MKDIR', None),
956 ('mktemp', 'HAVE_MKTEMP', None),
957 ('mkstemp', 'HAVE_MKSTEMP', None),
958 ('strerror', 'HAVE_STRERROR', None),
959 ('count', 'HAVE_STD_COUNT', '''
964 return std::count(a, a+5, 'l');
967 ('getcwd', 'HAVE_GETCWD', None),
968 ('setenv', 'HAVE_SETENV', None),
969 ('putenv', 'HAVE_PUTENV', None),
970 ('fcntl', 'HAVE_FCNTL', None),
973 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
974 '#include <streambuf>\n#include <istream>')
977 ('gdi32', 'HAVE_LIBGDI32'),
978 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
979 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
982 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
984 'Define is sys/types.h does not have pid_t',
988 (conf.CheckCXXGlobalCstd(),
990 'Define if your C++ compiler puts C library functions in the global namespace'
992 (conf.CheckMkdirOneArg(),
993 'MKDIR_TAKES_ONE_ARG',
994 'Define if mkdir takes only one argument.'
996 (conf.CheckLC_MESSAGES(),
998 'Define if your <locale.h> file defines LC_MESSAGES.'
1000 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1003 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1005 (env['nls'] and not included_gettext,
1007 'Define to 1 if using system gettext library'
1009 (env.has_key('warnings') and env['warnings'],
1011 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1013 (env.has_key('concept_checks') and env['concept_checks'],
1014 '_GLIBCXX_CONCEPT_CHECKS',
1015 'libstdc++ concept checking'
1017 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1019 'libstdc++ debug mode'
1021 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1022 '_GLIBCXX_DEBUG_PEDANTIC',
1023 'libstdc++ pedantic debug mode'
1025 (os.name != 'nt', 'BOOST_POSIX',
1026 'Indicates to boost which API to use (posix or windows).'
1028 (spell_engine is not None, spell_engine,
1029 'Spell engine to use'
1033 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1035 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1036 'Define to the address where bug reports for this package should be sent.'),
1037 ('#define PACKAGE_NAME "%s"' % package_name,
1038 'Define to the full name of this package.'),
1039 ('#define PACKAGE_STRING "%s"' % package_string,
1040 'Define to the full name and version of this package.'),
1041 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1042 'Define to the one symbol short name of this package.'),
1043 ('#define PACKAGE_VERSION "%s"' % package_version,
1044 'Define to the version of this package.'),
1045 ('#define BOOST_ALL_NO_LIB 1',
1046 'disable automatic linking of boost libraries.'),
1047 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1048 'Packaging method'),
1049 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1050 'Aiksaurus include file'),
1051 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1052 "Define to the type of arg 1 for `select'."),
1053 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1054 "Define to the type of arg 2, 3, 4 for `select'."),
1055 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1056 "Define to the type of arg 5 for `select'."),
1058 config_post = '''/************************************************************
1059 ** You should not need to change anything beyond this point */
1061 #ifndef HAVE_STRERROR
1062 #if defined(__cplusplus)
1065 char * strerror(int n);
1069 #ifndef HAVE_DECL_MKSTEMP
1070 #if defined(__cplusplus)
1077 #include <../boost/config.h>
1083 # these keys are needed in env
1084 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1085 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1086 'ICONV_LIB', 'AIKSAURUS_LIB']:
1087 # USE_ASPELL etc does not go through result
1088 if result.has_key(key):
1089 env[key] = result[key]
1090 env_cache[key] = env[key]
1093 # if nls=yes and gettext=included, create intl/config.h
1094 # intl/libintl.h etc
1096 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1097 if env['nls'] and included_gettext:
1099 print "Creating %s..." % intl_config_h
1101 # create intl/config.h
1102 result = utils.createConfigFile(conf,
1103 config_file = intl_config_h,
1104 config_pre = '''/* intl/config.h. Generated by SCons. */
1109 * This file is part of LyX, the document processor.
1110 * Licence details can be found in the file COPYING.
1112 * This is the compilation configuration file for LyX.
1113 * It was generated by scon.
1114 * You might want to change some of the defaults if something goes wrong
1115 * during the compilation.
1122 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1123 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1124 ('string.h', 'HAVE_STRING_H', 'c'),
1125 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1126 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1127 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1128 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1129 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1130 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1131 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1134 ('getcwd', 'HAVE_GETCWD', None),
1135 ('stpcpy', 'HAVE_STPCPY', None),
1136 ('strcasecmp', 'HAVE_STRCASECMP', None),
1137 ('strdup', 'HAVE_STRDUP', None),
1138 ('strtoul', 'HAVE_STRTOUL', None),
1139 ('alloca', 'HAVE_ALLOCA', None),
1140 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1141 ('mempcpy', 'HAVE_MEMPCPY', None),
1142 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1143 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1144 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1145 ('setlocale', 'HAVE_SETLOCALE', None),
1146 ('tsearch', 'HAVE_TSEARCH', None),
1147 ('getegid', 'HAVE_GETEGID', None),
1148 ('getgid', 'HAVE_GETGID', None),
1149 ('getuid', 'HAVE_GETUID', None),
1150 ('wcslen', 'HAVE_WCSLEN', None),
1151 ('asprintf', 'HAVE_ASPRINTF', None),
1152 ('wprintf', 'HAVE_WPRINTF', None),
1153 ('snprintf', 'HAVE_SNPRINTF', None),
1154 ('printf', 'HAVE_POSIX_PRINTF', None),
1155 ('fcntl', 'HAVE_FCNTL', None),
1158 ('intmax_t', 'HAVE_INTMAX_T', None),
1159 ('long double', 'HAVE_LONG_DOUBLE', None),
1160 ('long long', 'HAVE_LONG_LONG', None),
1161 ('wchar_t', 'HAVE_WCHAR_T', None),
1162 ('wint_t', 'HAVE_WINT_T', None),
1163 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1164 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1167 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1171 (conf.CheckLC_MESSAGES(),
1173 'Define if your <locale.h> file defines LC_MESSAGES.'
1175 (conf.CheckIconvConst(),
1177 'Define as const if the declaration of iconv() needs const.',
1178 '#define ICONV_CONST',
1179 '#define ICONV_CONST const',
1181 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1182 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1184 "Define to 1 if you have the `intmax_t' type."
1186 (env.has_key('nls') and env['nls'],
1188 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1191 config_post = '#endif'
1194 # these keys are needed in env
1195 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1196 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1197 # USE_ASPELL etc does not go through result
1198 if result.has_key(key):
1199 env[key] = result[key]
1200 env_cache[key] = env[key]
1204 # this comes as a big surprise, without this line
1205 # (doing nothing obvious), adding fast_start=yes
1206 # to a build with fast_start=no will result in a rebuild
1207 # Note that the exact header file to check does not matter
1208 conf.CheckCHeader('io.h')
1209 # only a few variables need to be rescanned
1210 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1211 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1212 'ICONV_LIB', 'AIKSAURUS_LIB']:
1213 env[key] = env_cache[key]
1216 if env['nls'] and included_gettext:
1217 # only a few variables need to be rescanned
1218 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1219 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1220 env[key] = env_cache[key]
1222 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1223 if env['nls'] and included_gettext:
1224 # libgnuintl.h.in => libintl.h
1225 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1226 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1227 [Copy('$TARGET', '$SOURCE')])
1230 # Finish auto-configuration
1233 #----------------------------------------------------------
1234 # Now set up our build process accordingly
1235 #----------------------------------------------------------
1240 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1241 # in their respective directory and specialized env.
1243 if frontend in ['qt2', 'qt3']:
1244 # note: env.Tool('qt') my set QT_LIB to qt
1246 frontend_libs = ['qt-mt']
1247 elif frontend == 'qt4':
1248 qt_libs = ['QtCore', 'QtGui']
1249 # set the right lib names
1250 if platform_name == 'win32':
1251 if mode == 'debug' and use_vc:
1252 qt_lib_suffix = 'd4'
1257 qt_lib_suffix = '_debug'
1260 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1262 print "Can not locate qt tools"
1263 print "What I get is "
1264 print " QTDIR: ", env['QTDIR']
1267 if platform_name in ['win32', 'cygwin']:
1268 # the final link step needs stdc++ to succeed under mingw
1269 # FIXME: shouldn't g++ automatically link to stdc++?
1271 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1273 system_libs = ['shlwapi', 'stdc++', 'z']
1274 elif platform_name == 'cygwin' and env['X11']:
1275 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1276 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1282 ('HAVE_ICONV', env['ICONV_LIB']),
1283 ('HAVE_LIBGDI32', 'gdi32'),
1284 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1285 ('USE_ASPELL', aspell_lib),
1286 ('USE_ISPELL', 'ispell'),
1287 ('USE_PSPELL', 'pspell'),
1292 system_libs.append(lib[1])
1295 # Build parameters CPPPATH etc
1298 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1301 # boost: for boost header files
1302 # BUILDDIR/common: for config.h
1303 # TOP_SRCDIR/src: for support/* etc
1305 env['CPPPATH'] += ['$TOP_SRCDIR/boost', '$BUILDDIR/common', '$TOP_SRCDIR/src']
1306 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1307 if env['nls'] and included_gettext:
1308 env['CPPPATH'].append('$BUILDDIR/intl')
1310 # QT_INC_PATH is not needed for *every* source file
1311 env['CPPPATH'].remove(qt_inc_path)
1314 # A Link script for cygwin see
1315 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1316 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1319 if platform_name == 'cygwin':
1320 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1321 ld_script = utils.installCygwinLDScript(ld_script_path)
1322 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1323 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1328 # fill in the version info
1329 env['VERSION_INFO'] = '''Configuration
1331 Special build flags: %s
1333 C Compiler flags: %s %s
1335 C++ Compiler LyX flags: %s
1336 C++ Compiler flags: %s %s
1338 Linker user flags: %s
1340 Builing directory: %s
1341 Local library directory: %s
1344 Frontend libraries: %s
1345 System libraries: %s
1346 include search path: %s
1352 ''' % (platform_name,
1353 env.subst('$CCFLAGS'), env.subst('$CC'),
1354 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1355 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1356 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1357 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1358 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1359 str(env['LIBPATH']), str(boost_libraries),
1360 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1361 frontend, packaging_method,
1362 prefix, env['LYX_DIR'])
1364 if frontend in ['qt2', 'qt3', 'qt4']:
1365 env['VERSION_INFO'] += ''' include dir: %s
1368 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1371 print env['VERSION_INFO']
1374 # Mingw command line may be too short for our link usage,
1375 # Here we use a trick from scons wiki
1376 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1378 # I also would like to add logging (commands only) capacity to the
1380 logfile = env.get('logfile', default_log_file)
1381 if logfile != '' or platform_name == 'win32':
1383 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1384 info = '''# This is a log of commands used by scons to build lyx
1388 ''' % (time.asctime(), ' '.join(sys.argv),
1389 env['VERSION_INFO'].replace('\n','\n# ')) )
1394 # -h will print out help info
1395 Help(opts.GenerateHelpText(env))
1397 # save environment settings (for fast_start option)
1398 cache_file = open(env_cache_file, 'w')
1399 cPickle.dump(env_cache, cache_file)
1403 #----------------------------------------------------------
1405 #----------------------------------------------------------
1406 # this has been the source of problems on some platforms...
1407 # I find that I need to supply it with full path name
1408 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1409 # this usage needs further investigation.
1410 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1412 print "Building all targets recursively"
1414 if env.has_key('rebuild'):
1415 rebuild_targets = env['rebuild'].split(',')
1417 rebuild_targets = None
1419 def libExists(libname):
1420 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1421 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1423 targets = BUILD_TARGETS
1424 # msvc need to pass full target name, so I have to look for path/lyx etc
1425 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1426 or 'install' in targets or 'all' in targets
1427 build_boost = (env['INCLUDED_BOOST'] and not libExists('boost_regex')) or 'boost' in targets
1428 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1429 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1430 build_mathed = build_lyx or 'mathed' in targets
1431 build_insets = build_lyx or 'insets' in targets
1432 build_frontends = build_lyx or 'frontends' in targets
1433 build_graphics = build_lyx or 'graphics' in targets
1434 build_controllers = build_lyx or 'controllers' in targets
1435 build_client = True in ['client' in x for x in targets] \
1436 or 'install' in targets or 'all' in targets
1437 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1438 or 'install' in targets or 'all' in targets
1439 build_lyxbase = build_lyx or 'lyxbase' in targets
1440 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1441 build_qt2 = (build_lyx and frontend == 'qt2') or 'qt2' in targets
1442 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1443 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1444 build_msvs_projects = use_vc and 'msvs_projects' in targets
1447 # now, if rebuild_targets is specified, do not rebuild some targets
1448 rebuild_targets = rebuild_targets
1450 def ifBuildLib(name, libname, old_value):
1451 # explicitly asked to rebuild
1452 if name in rebuild_targets:
1454 # else if not rebuild, and if the library already exists
1455 elif libExists(libname):
1457 # do not change the original value
1460 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1461 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1462 build_support = ifBuildLib('support', 'support', build_support)
1463 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1464 build_insets = ifBuildLib('insets', 'insets', build_insets)
1465 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1466 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1467 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1468 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1469 build_qt2 = ifBuildLib('qt2', 'qt2', build_qt2)
1470 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1471 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1473 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1487 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1489 boostenv = env.Copy()
1491 # boost use its own config.h
1492 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1493 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1495 for lib in boost_libs:
1496 print 'Processing files in boost/libs/%s/src...' % lib
1497 boostlib = boostenv.StaticLibrary(
1498 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1499 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/boost/libs/%s/src' % lib),
1500 pattern = '*.cpp', build_dir = '$BUILDDIR/boost/%s/src' % lib)
1502 Alias('boost', boostlib)
1509 intlenv = env.Copy()
1511 print "Processing files in intl..."
1513 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1515 # we need the original C compiler for these files
1516 intlenv['CC'] = C_COMPILER
1517 intlenv['CCFLAGS'] = C_CCFLAGS
1519 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1520 # intl does not use global config.h
1521 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1523 intlenv.Append(CCFLAGS = [
1524 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1525 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1526 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1528 '-DENABLE_RELOCATABLE=1',
1530 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1532 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1533 '-Drelocate=libintl_relocate',
1534 '-DDEPENDS_ON_LIBICONV=1',
1539 intl = intlenv.StaticLibrary(
1540 target = '$LOCALLIBPATH/included_intl',
1542 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/intl'), pattern = '*.c',
1543 exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
1544 build_dir = '$BUILDDIR/intl')
1550 # Now, src code under src/
1552 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1559 print "Processing files in src/support..."
1561 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1563 support = env.StaticLibrary(
1564 target = '$LOCALLIBPATH/support',
1565 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/support'), pattern = lyx_ext,
1566 exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'os_os2.C', 'atexit.c'],
1567 include = ['package.C'], build_dir = '$BUILDDIR/common/support')
1569 Alias('support', support)
1576 print "Processing files in src/mathed..."
1578 mathed = env.StaticLibrary(
1579 target = '$LOCALLIBPATH/mathed',
1580 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/mathed'),
1582 exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
1583 build_dir = '$BUILDDIR/common/mathed')
1585 Alias('mathed', mathed)
1592 print "Processing files in src/insets..."
1594 insets = env.StaticLibrary(
1595 target = '$LOCALLIBPATH/insets',
1596 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/insets'),
1598 exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
1600 Alias('insets', insets)
1607 print "Processing files in src/frontends..."
1609 frontends = env.StaticLibrary(
1610 target = '$LOCALLIBPATH/frontends',
1611 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends'), pattern = lyx_ext,
1612 build_dir = '$BUILDDIR/common/frontends')
1614 Alias('frontends', frontends)
1621 print "Processing files in src/graphics..."
1623 graphics = env.StaticLibrary(
1624 target = '$LOCALLIBPATH/graphics',
1625 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/graphics'), pattern = lyx_ext,
1626 build_dir = '$BUILDDIR/common/graphics')
1628 Alias('graphics', graphics)
1631 if build_controllers:
1633 # src/frontends/controllers
1635 print "Processing files in src/frontends/controllers..."
1637 controllers = env.StaticLibrary(
1638 target = '$LOCALLIBPATH/controllers',
1639 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/controllers'), pattern = lyx_ext,
1640 build_dir = '$BUILDDIR/common/frontends/controllers')
1642 Alias('controllers', controllers)
1646 # src/frontend/qt2/3/4
1648 if build_qt2 or build_qt3 or build_qt4:
1649 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1653 print "Processing files in src/frontends/qt2..."
1656 # disable auto scan to speed up non build time
1657 qt2env['QT_AUTOSCAN'] = 0
1658 qt2env['QT_MOCHPREFIX'] = ''
1663 qt2env.AppendUnique(CPPPATH = [
1665 '$BUILDDIR/common/images',
1666 '$BUILDDIR/common/frontends',
1667 '$BUILDDIR/common/frontends/qt2',
1668 '$BUILDDIR/common/frontends/controllers',
1672 qt2_moc_files = ["$BUILDDIR/common/frontends/qt2/%s" % x for x in Split('''
1675 FileDialog_private.C
1714 QSpellcheckerDialog.C
1716 QTabularCreateDialog.C
1731 # manually moc and uic files for better performance
1732 qt2_moced_files = [qt2env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt2_moc_files]
1734 qt2_uiced_files = [qt2env.Uic('$BUILDDIR/common/frontends/qt2/ui/'+x) for x in \
1735 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/ui'), pattern = '*.ui')]
1737 qt2_uiced_cc_files = []
1738 for x in qt2_uiced_files:
1739 qt2_uiced_cc_files.extend(x[1:])
1741 qt2 = qt2env.StaticLibrary(
1742 target = '$LOCALLIBPATH/qt2',
1743 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt2/'), pattern = lyx_ext,
1744 build_dir = '$BUILDDIR/common/frontends/qt2') + qt2_moced_files + qt2_uiced_cc_files
1750 print "Processing files in src/frontends/qt3..."
1753 # disable auto scan to speed up non build time
1754 qt3env['QT_AUTOSCAN'] = 0
1755 qt3env['QT_MOCHPREFIX'] = ''
1760 qt3env.AppendUnique(CPPPATH = [
1762 '$BUILDDIR/common/images',
1763 '$BUILDDIR/common/frontends',
1764 '$BUILDDIR/common/frontends/qt3',
1765 '$BUILDDIR/common/frontends/controllers',
1769 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
1772 FileDialog_private.C
1812 QSpellcheckerDialog.C
1814 QTabularCreateDialog.C
1829 # manually moc and uic files for better performance
1830 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1832 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1833 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/ui'), pattern = '*.ui')]
1835 qt3_uiced_cc_files = []
1836 for x in qt3_uiced_files:
1837 qt3_uiced_cc_files.extend(x[1:])
1839 qt3 = qt3env.StaticLibrary(
1840 target = '$LOCALLIBPATH/qt3',
1841 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt3/'), pattern = lyx_ext,
1842 build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
1848 print "Processing files in src/frontends/qt4..."
1851 qt4env['QT_AUTOSCAN'] = 0
1853 # local qt4 toolset from
1854 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1856 # NOTE: I have to patch qt4.py since it does not automatically
1857 # process .C file!!! (add to cxx_suffixes )
1859 qt4env.Tool('qt4', [scons_dir])
1860 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1862 qt4env.AppendUnique(CPPPATH = [
1864 '$BUILDDIR/common/images',
1865 '$BUILDDIR/common/frontends',
1866 '$BUILDDIR/common/frontends/qt4',
1867 '$BUILDDIR/common/frontends/controllers',
1872 # FIXME: replace by something from pkg_config
1873 qt4env.Append(CCFLAGS = [
1875 '-DQT_CLEAN_NAMESPACE',
1883 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
1886 FileDialog_private.C
1929 QSpellcheckerDialog.C
1931 QTabularCreateDialog.C
1950 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1951 utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4/ui'), pattern = '*.ui',
1952 build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
1955 # moc qt4_moc_files, the moced files are included in the original files
1957 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1959 qt4 = qt4env.StaticLibrary(
1960 target = '$LOCALLIBPATH/qt4',
1961 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/frontends/qt4'), pattern = lyx_ext,
1962 exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
1971 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1973 print "Processing files in src/client..."
1975 if env['HAVE_FCNTL']:
1976 client = env.Program(
1977 target = '$BUILDDIR/common/client/lyxclient',
1978 LIBS = ['support'] + intl_libs + system_libs +
1979 socket_libs + boost_libraries,
1980 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/client'), pattern = lyx_ext,
1981 build_dir = '$BUILDDIR/common/client')
1983 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1984 client, [Copy('$TARGET', '$SOURCE')]))
1987 Alias('client', client)
1994 print "Processing files in src/tex2lyx..."
1996 tex2lyx_env = env.Copy()
1998 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1999 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
2001 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
2002 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
2003 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
2004 [Copy('$TARGET', '$SOURCE')])
2006 tex2lyx = tex2lyx_env.Program(
2007 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
2008 LIBS = ['support'] + boost_libraries + system_libs,
2009 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src/tex2lyx'), pattern = lyx_ext,
2010 include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C',
2011 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
2012 build_dir = '$BUILDDIR/common/tex2lyx')
2014 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
2015 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
2016 Alias('tex2lyx', tex2lyx)
2023 print "Processing files in src..."
2025 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
2027 lyx_post_source = Split('''
2036 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
2037 lyx_post_source.append('aspell.C')
2038 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
2039 lyx_post_source.append('pspell.C')
2040 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
2041 lyx_post_source.append('ispell.C')
2043 # msvc requires at least one source file with main()
2044 # so I exclude main.C from lyxbase
2045 lyxbase_pre = env.StaticLibrary(
2046 target = '$LOCALLIBPATH/lyxbase_pre',
2047 source = utils.globSource(dir = env.subst('$TOP_SRCDIR/src'), pattern = lyx_ext,
2048 exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C',
2049 'ispell.C', 'Variables.C', 'Sectioning.C'],
2050 include = ['version.C'], build_dir = '$BUILDDIR/common')
2052 lyxbase_post = env.StaticLibrary(
2053 target = '$LOCALLIBPATH/lyxbase_post',
2054 source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
2056 Alias('lyxbase', lyxbase_pre)
2057 Alias('lyxbase', lyxbase_post)
2062 # Build lyx with given frontend
2065 target = '$BUILDDIR/$frontend/lyx',
2066 source = ['$BUILDDIR/common/main.C'],
2084 # [/path/to/lyx.ext] => lyx-qt3.ext
2085 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
2086 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
2087 [Copy('$TARGET', '$SOURCE')]))
2091 if build_msvs_projects:
2092 def build_project(target, dir, full_target = None,
2093 src_pattern = lyx_ext, include = [], resource = None, rebuildTargetOnly = True):
2094 ''' build mavs project files
2095 target: alias (correspond to directory name)
2096 dir: source directory or directories (a list)
2097 full_target: full path/filename of the target
2098 src_pattern: glob pattern
2099 include: files to include into source
2100 resource: directory or directories with resource (.ui) files
2101 rebuildTargetOnly: whether or not only rebuild this target
2103 For non-debug-able targets like static libraries, target (alias) is
2104 enough to build the target. For executable targets, msvs need to know
2105 the full path to start debug them.
2107 if resource is not None:
2108 res = utils.globSource(dir = env.subst('$TOP_SRCDIR/'+resource), pattern = '*.ui',
2109 build_dir = env.subst('$TOP_SRCDIR/'+resource))
2112 if rebuildTargetOnly:
2113 cmds = 'faststart=yes rebuild='+target
2115 cmds = 'faststart=yes'
2116 if type(dir) == type([]):
2120 src.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2121 pattern = src_pattern, include = include,
2122 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2123 inc.extend(utils.globSource(dir = env.subst('$TOP_SRCDIR/' + d),
2125 build_dir = env.subst('$TOP_SRCDIR/' + d) ))
2127 src = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2128 pattern = src_pattern, include = include,
2129 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2130 inc = utils.globSource(dir = env.subst('$TOP_SRCDIR/' + dir),
2132 build_dir = env.subst('$TOP_SRCDIR/' + dir) )
2133 if full_target is None:
2134 build_target = target
2136 build_target = full_target
2138 proj = env.MSVSProject(
2139 target = target + env['MSVSPROJECTSUFFIX'],
2141 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
2144 buildtarget = build_target,
2148 Alias('msvs_projects', proj)
2150 build_project('boost', ['boost/libs/%s/src' % x for x in boost_libs],
2151 src_pattern = '*.cpp')
2153 build_project('intl', 'intl', src_pattern = '*.c')
2155 build_project('support', 'src/support', include=['package.C.in'])
2157 build_project('mathed', 'src/mathed')
2159 build_project('insets', 'src/insets')
2161 build_project('frontends', 'src/frontends')
2163 build_project('graphics', 'src/graphics')
2165 build_project('controllers', 'src/frontends/controllers')
2167 build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
2169 build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
2171 build_project('client', 'src/client', rebuildTargetOnly = False,
2172 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2174 build_project('tex2lyx', 'src/tex2lyx', rebuildTargetOnly = False,
2175 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2177 build_project('lyxbase', 'src')
2179 if frontend == 'qt3':
2180 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2181 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2182 'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
2183 rebuildTargetOnly = False,
2184 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2186 build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
2187 'src/frontends', 'src/graphics', 'src/frontends/controllers',
2188 'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
2189 rebuildTargetOnly = False,
2190 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2197 print 'Processing files in po...'
2202 # files to translate
2203 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2204 # possibly *only* handle these languages
2206 if env.has_key('languages'):
2207 languages = env.make_list(env['lanauges'])
2208 # use defulat msgfmt
2209 if not env['MSGFMT']:
2210 print 'msgfmt does not exist. Can not process po files'
2213 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2216 for f in transfiles:
2218 fname = os.path.split(f)[1]
2220 country = fname.split('.')[0]
2222 if not languages or country in languages:
2223 gmo_files.extend(env.Transfiles(f))
2226 if 'install' in targets:
2228 # install to DESTDIR or prefix
2229 dest_dir = env.Dir(env.get('DESTDIR', prefix)).abspath
2230 # if dest_dir is different from prefix.
2231 if env.has_key('exec_prefix'):
2232 bin_dest_dir = Dir(env['exec_prefix']).abspath
2234 bin_dest_dir = os.path.join(dest_dir, 'bin')
2236 share_dest_dir = os.path.join(dest_dir, share_dir + program_suffix)
2238 share_dest_dir = os.path.join(dest_dir, share_dir)
2239 man_dest_dir = os.path.join(dest_dir, man_dir)
2240 locale_dest_dir = os.path.join(dest_dir, locale_dir)
2241 # create the directory if needed
2242 if not os.path.isdir(dest_dir):
2244 os.makedirs(dest_dir)
2247 if not os.path.isdir(dest_dir):
2248 print 'Can not create directory', dest_dir
2253 # do not install these files
2254 exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile',
2255 'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
2257 def install(dest, src):
2258 ''' recusive installation of src to dest '''
2259 # separate file and directory
2260 files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
2261 dirs = filter(os.path.isdir, src)
2263 env.Install(dest, files)
2267 ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
2268 glob.glob(os.path.join(dir, '*'))) )
2271 # executables (some of them may be none)
2274 version_suffix = program_suffix
2279 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2280 target = os.path.join(bin_dest_dir, target_name)
2281 env.InstallAs(target, lyx)
2282 Alias('install', target)
2283 # install lyx as lyx-qt3
2284 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2285 target = os.path.join(bin_dest_dir, target_name)
2286 env.InstallAs(target, lyx)
2287 Alias('install', target)
2290 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2291 target = os.path.join(bin_dest_dir, target_name)
2292 env.InstallAs(target, tex2lyx)
2293 Alias('install', target)
2295 # install lyxclient, may not exist
2297 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2298 target = os.path.join(bin_dest_dir, target_name)
2299 env.InstallAs(target, client)
2300 Alias('install', target)
2303 dirs = install(share_dest_dir,
2304 [env.subst('$TOP_SRCDIR/lib/') + file for file in ['configure.py', 'encodings',
2305 'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
2306 'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts',
2307 'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc', 'ui']]
2309 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2310 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2311 Alias('install', dirs)
2313 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2314 env.subst('$TOP_SRCDIR/lyx.man'))
2315 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2316 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2317 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2318 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2319 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2320 x in ['lyx', 'tex2lyx', 'lyxclient']])
2322 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2323 for gmo in gmo_files:
2324 lan = os.path.split(str(gmo))[1].split('.')[0]
2325 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2326 env.InstallAs(dest_file, gmo)
2327 Alias('install', dest_file)
2331 Alias('all', ['lyx', 'client', 'tex2lyx'])