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
20 # import all file lists
21 from scons_manifest import *
23 #----------------------------------------------------------
24 # Required runtime environment
25 #----------------------------------------------------------
27 # scons asks for 1.5.2, lyx requires 2.3
28 EnsurePythonVersion(2, 3)
29 # Please use at least 0.96.92 (not 0.96.1)
30 EnsureSConsVersion(0, 96)
31 # also check for minor version number for scons 0.96
32 from SCons import __version__
33 version = map(int, __version__.split('.'))
34 if version[0] == 0 and version[1] == 96 and version[2] < 92:
35 print "Scons >= 0.96.92 is required."
38 # determine where I am ...
40 # called as 'cd development/scons; scons'
41 if os.path.isfile('SConstruct'):
44 # called as 'scons -f development/scons/SConstruct'
47 scons_dir = 'development/scons'
50 #----------------------------------------------------------
52 #----------------------------------------------------------
54 # some global settings
56 package_version = '1.5.0svn'
57 boost_version = '1_33_1'
60 default_build_mode = 'debug'
64 package_bugreport = 'lyx-devel@lists.lyx.org'
66 package_tarname = 'lyx'
67 package_string = '%s %s' % (package_name, package_version)
69 # various cache/log files
70 default_log_file = 'scons_lyx.log'
71 env_cache_file = 'env.cache'
74 #----------------------------------------------------------
75 # platform dependent settings
76 #----------------------------------------------------------
79 platform_name = 'win32'
80 default_frontend = 'qt4'
81 default_prefix = 'c:/program files/lyx'
82 default_with_x = False
83 default_packaging_method = 'windows'
84 elif os.name == 'posix' and sys.platform != 'cygwin':
85 platform_name = sys.platform
86 default_frontend = 'qt3'
87 default_prefix = '/usr/local'
89 default_packaging_method = 'posix'
90 elif os.name == 'posix' and sys.platform == 'cygwin':
91 platform_name = 'cygwin'
92 default_frontend = 'qt3'
93 default_prefix = '/usr'
95 default_packaging_method = 'posix'
96 elif os.name == 'darwin':
97 platform_name = 'macosx'
98 default_frontend = 'qt3'
99 # FIXME: macOSX default prefix?
101 default_with_x = False
102 default_packaging_method = 'macosx'
103 else: # unsupported system, assume posix behavior
104 platform_name = 'others'
105 default_frontend = 'qt3'
107 default_with_x = True
108 default_packaging_method = 'posix'
110 #---------------------------------------------------------
112 #----------------------------------------------------------
114 # You can set perminant default values in config.py
115 if os.path.isfile('config.py'):
116 print "Getting options from config.py..."
117 print open('config.py').read()
119 opts = Options(['config.py'])
122 EnumOption('frontend', 'Main GUI', default_frontend,
123 allowed_values = ('qt3', 'qt4', 'gtk') ),
124 # debug or release build
125 EnumOption('mode', 'Building method', default_build_mode,
126 allowed_values = ('debug', 'release') ),
129 'Use included, system boost library, or try sytem boost first.',
130 'auto', allowed_values = (
131 'auto', # detect boost, if not found, use included
132 'included', # always use included boost
133 'system', # always use system boost, fail if can not find
136 EnumOption('gettext',
137 'Use included, system gettext library, or try sytem gettext first',
138 'auto', allowed_values = (
139 'auto', # detect gettext, if not found, use included
140 'included', # always use included gettext
141 'system', # always use system gettext, fail if can not find
144 EnumOption('spell', 'Choose spell checker to use.', 'auto',
145 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
147 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
148 allowed_values = ('windows', 'posix', 'macosx')),
150 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
151 # No precompiled header support (too troublesome to make it work for msvc)
152 # BoolOption('pch', 'Whether or not use pch', False),
153 # enable assertion, (config.h has ENABLE_ASSERTIOS
154 BoolOption('assertions', 'Use assertions', True),
155 # enable warning, (config.h has WITH_WARNINGS)
156 # default to False since MSVC does not have #warning
157 BoolOption('warnings', 'Use warnings', False),
158 # config.h define _GLIBCXX_CONCEPT_CHECKS
159 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
160 BoolOption('concept_checks', 'Enable concept checks', True),
162 BoolOption('nls', 'Whether or not use native language support', True),
164 BoolOption('profiling', 'Whether or not enable profiling', False),
165 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
166 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
168 BoolOption('X11', 'Use x11 windows system', default_with_x),
169 # use MS VC++ to build lyx
170 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
172 PathOption('qt_dir', 'Path to qt directory', None),
174 PathOption('qt_inc_path', 'Path to qt include directory', None),
176 PathOption('qt_lib_path', 'Path to qt library directory', None),
177 # extra include and libpath
178 PathOption('extra_inc_path', 'Extra include path', None),
180 PathOption('extra_lib_path', 'Extra library path', None),
182 PathOption('extra_bin_path', 'A convenient way to add a path to $PATH', None),
184 PathOption('extra_inc_path1', 'Extra include path', None),
186 PathOption('extra_lib_path1', 'Extra library path', None),
187 # rebuild only specifed, comma separated targets
188 ('rebuild', '''rebuild only specifed, comma separated targets.
189 yes or all (default): rebuild everything
190 no or none: rebuild nothing (usually used for installation)
191 comp1,comp2,...: rebuild specified targets''', None),
192 # can be set to a non-existing directory
193 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
194 # build directory, will use $mode if not set
195 ('build_dir', 'Build directory', None),
197 ('version_suffix', 'install lyx as lyx-suffix', None),
198 # how to load options
199 ('load_option', '''load option from previous scons run. option can be
200 yes (default): load all options
201 no: do not load any option
202 opt1,opt2: load specified options
203 -opt1,opt2: load all options other than specified ones''', 'yes'),
205 ('optimization', 'optimization CCFLAGS option.', None),
207 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
209 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
210 # provided for backward compatibility
211 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
212 # environment variable can be set as options.
213 ('DESTDIR', 'install to DESTDIR', None),
214 ('CC', 'replace default $CC', None),
215 ('LINK', 'replace default $LINK', None),
216 ('CPP', 'replace default $CPP', None),
217 ('CXX', 'replace default $CXX', None),
218 ('CXXCPP', 'replace default $CXXCPP', None),
219 ('CCFLAGS', 'replace default $CCFLAGS', None),
220 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
221 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
225 all_options = [x.key for x in opts.options]
227 # copied from SCons/Options/BoolOption.py
228 # We need to use them before a boolean ARGUMENTS option is available
230 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
231 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
233 # whether or not use current config.h, and cached tests
235 # if fast_start=yes (default), load variables from env_cache_file
236 if (not ARGUMENTS.has_key('fast_start') or \
237 ARGUMENTS['fast_start'] in true_strings) \
238 and os.path.isfile(env_cache_file):
240 cache_file = open(env_cache_file)
241 env_cache = cPickle.load(cache_file)
243 print '------------ fast_start mode --------------------'
244 print ' Use cached test results and current config.h'
245 print ' use fast_start=no to override'
251 # if load_option=yes (default), load saved comand line options
253 # This option can take value yes/no/opt1,opt2/-opt1,opt2
254 # and tries to be clever in choosing options to load
255 if (not ARGUMENTS.has_key('load_option') or \
256 ARGUMENTS['load_option'] not in false_strings) \
257 and os.path.isfile(env_cache_file):
258 cache_file = open(env_cache_file)
259 opt_cache = cPickle.load(cache_file)['arg_cache']
261 # import cached options, but we should ignore qt_dir when frontend changes
262 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
263 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
264 and opt_cache.has_key('qt_dir'):
265 opt_cache.pop('qt_dir')
266 # some options will require full rebuild
267 # these are in general things that will change config.h
268 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
269 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
270 ARGUMENTS[arg] != opt_cache[arg]):
272 print " ** fast_start is disabled because of the change of option", arg
275 # and we do not cache some options (dest_dir is obsolete)
276 for arg in ['fast_start', 'load_option', 'dest_dir']:
277 if opt_cache.has_key(arg):
279 # remove obsolete cached keys (well, SConstruct is evolving. :-)
280 for arg in opt_cache.keys():
281 if arg not in all_options:
282 print 'Option %s is obsolete, do not load it' % arg
284 # now, if load_option=opt1,opt2 or -opt1,opt2
285 if ARGUMENTS.has_key('load_option') and \
286 ARGUMENTS['load_option'] not in true_strings + false_strings:
287 # if -opt1,opt2 is specified, do not load these options
288 if ARGUMENTS['load_option'][0] == '-':
289 for arg in ARGUMENTS['load_option'][1:].split(','):
290 if opt_cache.has_key(arg):
292 # if opt1,opt2 is specified, only load specified options
294 args = ARGUMENTS['load_option'].split(',')
295 for arg in opt_cache.keys():
298 # now restore options as if entered from command line
299 for key in opt_cache.keys():
300 if not ARGUMENTS.has_key(key):
301 ARGUMENTS[key] = opt_cache[key]
302 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
305 # check if there is unused (or misspelled) argument
306 for arg in ARGUMENTS.keys():
307 if arg not in all_options:
309 print "Unknown option '%s'... exiting." % arg
311 print "Available options are (check 'scons -help' for details):"
312 print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options)))
316 env_cache['arg_cache'] = ARGUMENTS
319 #---------------------------------------------------------
320 # Setting up environment
321 #---------------------------------------------------------
323 # I do not really like ENV=os.environ, but you may add it
324 # here if you experience some environment related problem
325 env = Environment(options = opts)
327 # set individual variables since I do not really like ENV = os.environ
328 env['ENV']['PATH'] = os.environ.get('PATH')
329 env['ENV']['HOME'] = os.environ.get('HOME')
330 # these are defined for MSVC
331 env['ENV']['LIB'] = os.environ.get('LIB')
332 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
334 # for simplicity, use var instead of env[var]
335 frontend = env['frontend']
336 prefix = env['prefix']
339 if platform_name == 'win32':
340 if env.has_key('use_vc'):
341 use_vc = env['use_vc']
342 if WhereIs('cl.exe') is None:
343 print "cl.exe is not found. Are you using the MSVC environment?"
345 elif WhereIs('cl.exe') is not None:
352 # lyx will be built to $build/build_dir so it is possible
353 # to build multiple build_dirs using the same source
354 # $mode can be debug or release
355 if env.has_key('build_dir') and env['build_dir'] is not None:
356 # create the directory if needed
357 if not os.path.isdir(env['build_dir']):
359 os.makedirs(env['build_dir'])
362 if not os.path.isdir(env['build_dir']):
363 print 'Can not create directory', env['build_dir']
365 env['BUILDDIR'] = env['build_dir']
367 # Determine the name of the build $mode
368 env['BUILDDIR'] = '#' + mode
370 # all built libraries will go to build_dir/libs
371 # (This is different from the make file approach)
372 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
373 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
376 # Here is a summary of variables defined in env
378 # 2. undefined options with a non-None default value
379 # 3. compiler commands and flags like CCFLAGS.
380 # MSGFMT used to process po files
381 # 4. Variables that will be used to replace variables in some_file.in
382 # src/support/package.C.in:
383 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
384 # lib/lyx2lyx/lyx2lyx_version.py.in
387 # PACKAGE_VERSION, VERSION_INFO
389 # full path name is used to build msvs project files
390 # and to replace TOP_SRCDIR in package.C
391 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
392 # needed by src/version.C.in => src/version.C
393 env['PACKAGE_VERSION'] = package_version
395 # determine share_dir etc
396 packaging_method = env.get('packaging')
397 if packaging_method == 'windows':
398 share_dir = 'Resources'
399 man_dir = 'Resources/man/man1'
400 locale_dir = 'Resources/locale'
401 default_prefix = 'c:/program files/lyx'
403 share_dir = 'share/lyx'
405 locale_dir = 'share/locale'
406 default_prefix = '/usr/local/'
408 # install to default_prefix by default
409 # program suffix: can be yes, or a string
410 if env.has_key('version_suffix'):
411 if env['version_suffix'] in true_strings:
412 program_suffix = package_version
413 elif env['version_suffix'] in false_strings:
416 program_suffix = env['version_suffix']
419 # used by package.C.in
420 env['PROGRAM_SUFFIX'] = program_suffix
422 # whether or not add suffix to file and directory names
423 add_suffix = packaging_method != 'windows'
424 # LYX_DIR are different (used in package.C.in)
426 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
428 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
429 # we need absolute path for package.C
430 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
433 #---------------------------------------------------------
434 # Setting building environment (Tools, compiler flags etc)
435 #---------------------------------------------------------
437 # Since Tool('mingw') will reset CCFLAGS etc, this should be
438 # done before getEnvVariable
439 if platform_name == 'win32':
445 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
447 # we differentiate between hard-coded options and default options
448 # hard-coded options are required and will always be there
449 # default options can be replaced by enviromental variables or command line options
450 CCFLAGS_required = []
451 LINKFLAGS_required = []
454 # under windows, scons is confused by .C/.c and uses gcc instead of
455 # g++. I am forcing the use of g++ here. This is expected to change
456 # after lyx renames all .C files to .cpp
458 # save the old c compiler and CCFLAGS (used by libintl)
459 C_COMPILER = env.subst('$CC')
460 C_CCFLAGS = env.subst('$CCFLAGS').split()
461 # if we use ms vc, the commands are fine (cl.exe and link.exe)
463 # /TP treat all source code as C++
464 # C4819: The file contains a character that cannot be represented
465 # in the current code page (number)
466 # C4996: foo was decleared deprecated
467 CCFLAGS_required.extend(['/TP', '/EHsc'])
468 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo'])
470 if env.has_key('CXX') and env['CXX']:
471 env['CC'] = env.subst('$CXX')
472 env['LINK'] = env.subst('$CXX')
477 # for debug/release mode
478 if env.has_key('optimization') and env['optimization'] is not None:
479 # if user supplies optimization flags, use it anyway
480 CCFLAGS_required.extend(env['optimization'].split())
481 # and do not use default
482 set_default_optimization_flags = False
484 set_default_optimization_flags = True
488 CCFLAGS_required.append('/Zi')
489 LINKFLAGS_required.extend(['/debug', '/map'])
491 CCFLAGS_required.append('-g')
492 CCFLAGS_default.append('-O')
493 elif mode == 'release' and set_default_optimization_flags:
495 CCFLAGS_default.append('/O2')
497 CCFLAGS_default.append('-O2')
499 # msvc uses separate tools for profiling
500 if env.has_key('profiling') and env['profiling']:
502 print 'Visual C++ does not use profiling options'
504 CCFLAGS_required.append('-pg')
505 LINKFLAGS_required.append('-pg')
507 if env.has_key('warnings') and env['warnings']:
509 CCFLAGS_default.append('/W2')
511 # Note: autotools detect gxx version and pass -W for 3.x
512 # and -Wextra for other versions of gcc
513 CCFLAGS_default.append('-Wall')
515 # Now, set the variables as follows:
516 # 1. if command line option exists: replace default
517 # 2. then if s envronment variable exists: replace default
518 # 3. set variable to required + default
519 def setEnvVariable(env, name, required = None, default = None, split = True):
520 ''' env: environment to set variable
522 required: hardcoded options
523 default: default options that can be replaced by command line or
524 environment variables
525 split: whether or not split obtained variable like '-02 -g'
527 # first try command line argument (override environment settings)
528 if ARGUMENTS.has_key(name):
529 default = ARGUMENTS[name]
531 default = default.split()
532 # then use environment default
533 elif os.environ.has_key(name):
534 print "Acquiring varaible %s from system environment: %s" % (name, os.environ[name])
535 default = os.environ[name]
537 default = default.split()
539 if required is not None:
541 if default is not None:
542 if env.has_key(name) and env[name] != default:
547 setEnvVariable(env, 'DESTDIR', split=False)
548 setEnvVariable(env, 'CC')
549 setEnvVariable(env, 'LINK')
550 setEnvVariable(env, 'CPP')
551 setEnvVariable(env, 'CXX')
552 setEnvVariable(env, 'CXXCPP')
553 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
554 setEnvVariable(env, 'CXXFLAGS')
555 setEnvVariable(env, 'CPPFLAGS')
556 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
558 # if DESTDIR is not set...
559 if env.has_key('dest_dir'):
560 print "This option is obsolete. Please use DESTDIR instead."
561 env['DESTDIR'] = env['dest_dir']
564 #---------------------------------------------------------
565 # Frontend related variables (QTDIR etc)
566 #---------------------------------------------------------
568 if env.has_key('qt_dir') and env['qt_dir']:
569 env['QTDIR'] = env['qt_dir']
570 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
571 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
573 # if there is a valid QTDIR, set path for lib and bin directories
574 if env.has_key('QTDIR'):
575 # add path to the qt tools
576 if os.path.isdir(os.path.join(env['QTDIR'], 'lib')):
577 env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')])
578 # set environment so that moc etc can be found even if its path is not set properly
579 if os.path.isdir(os.path.join(env['QTDIR'], 'bin')):
580 os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin')
581 env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin'))
583 if env.has_key('qt_lib_path') and env['qt_lib_path']:
584 qt_lib_path = env.subst('$qt_lib_path')
585 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
586 qt_lib_path = env.subst('$QTDIR/lib')
587 # this is the path for cygwin.
588 elif os.path.isdir(os.path.join('/usr/lib/', frontend, 'lib')):
589 qt_lib_path = '/usr/lib/%s/lib' % frontend
591 print "Qt library directory is not found. Please specify it using qt_lib_path"
593 env.AppendUnique(LIBPATH = [qt_lib_path])
594 # qt4 seems to be using pkg_config
595 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
597 if env.has_key('qt_inc_path') and env['qt_inc_path']:
598 qt_inc_path = env['qt_inc_path']
599 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
600 qt_inc_path = '$QTDIR/include'
601 # this is the path for cygwin.
602 elif os.path.isdir('/usr/include/' + frontend):
603 qt_inc_path = '/usr/include/' + frontend
605 print "Qt include directory not found. Please specify it using qt_inc_path"
607 # Note that this CPPPATH is for testing only
608 # it will be removed before calling SConscript
609 env['CPPPATH'] = [qt_inc_path]
612 # extra_inc_path and extra_lib_path
615 if env.has_key('extra_inc_path') and env['extra_inc_path']:
616 extra_inc_paths.append(env['extra_inc_path'])
617 if env.has_key('extra_lib_path') and env['extra_lib_path']:
618 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
619 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
620 extra_inc_paths.append(env['extra_inc_path1'])
621 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
622 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
623 if env.has_key('extra_bin_path') and env['extra_bin_path']:
624 # only the first one is needed (a scons bug?)
625 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
626 env.PrependENVPath('PATH', env['extra_bin_path'])
627 # extra_inc_paths will be used later by intlenv etc
628 env.AppendUnique(CPPPATH = extra_inc_paths)
631 #----------------------------------------------------------
633 #----------------------------------------------------------
635 conf = Configure(env,
637 'CheckPkgConfig' : utils.checkPkgConfig,
638 'CheckPackage' : utils.checkPackage,
639 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
640 'CheckSelectArgType' : utils.checkSelectArgType,
641 'CheckBoostLibraries' : utils.checkBoostLibraries,
642 'CheckCommand' : utils.checkCommand,
643 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
644 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
645 'CheckIconvConst' : utils.checkIconvConst,
649 # pkg-config? (if not, we use hard-coded options)
651 if conf.CheckPkgConfig('0.15.0'):
652 env['HAS_PKG_CONFIG'] = True
654 print 'pkg-config >= 0.1.50 is not found'
655 env['HAS_PKG_CONFIG'] = False
656 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
658 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
660 # zlib? This is required. (fast_start assumes the existance of zlib)
662 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
663 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
664 print 'Did not find zdll.lib or zlib.h, exiting!'
670 # qt3 does not use pkg_config
671 if frontend == 'qt3':
672 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();'):
673 print 'Did not find qt libraries, exiting!'
675 elif frontend == 'qt4':
677 # first: try pkg_config
678 if env['HAS_PKG_CONFIG']:
679 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
680 # FIXME: use pkg_config information?
681 #env['QT4_PKG_CONFIG'] = succ
682 # second: try to link to it
684 # Under linux, I can test the following perfectly
685 # Under windows, lib names need to passed as libXXX4.a ...
686 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
687 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
688 # third: try to look up the path
691 for lib in ['QtCore', 'QtGui']:
692 # windows version has something like QtGui4 ...
693 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
694 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
697 # still can not find it
699 print "Qt4 libraries are found."
701 print 'Did not find qt libraries, exiting!'
704 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
707 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
709 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
710 if os.path.isfile(manifest):
711 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
716 if conf.CheckLib('socket'):
717 socket_libs.append('socket')
718 # nsl is the network services library and provides a
719 # transport-level interface to networking services.
720 if conf.CheckLib('nsl'):
721 socket_libs.append('nsl')
722 env_cache['SOCKET_LIBS'] = socket_libs
724 socket_libs = env_cache['SOCKET_LIBS']
726 # check available boost libs (since lyx1.4 does not use iostream)
728 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
729 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
730 boost_libs.append(lib)
733 # check boost libraries
734 boost_opt = ARGUMENTS.get('boost', 'auto')
735 # check for system boost
736 lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
737 inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
738 # default to $BUILDDIR/libs (use None since this path will be added anyway)
740 # here I assume that all libraries are in the same directory
741 if boost_opt == 'included':
742 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
743 included_boost = True
744 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
745 elif boost_opt == 'auto':
746 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
747 # if not found, use local boost
749 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
750 included_boost = True
751 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
753 included_boost = False
754 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
755 elif boost_opt == 'system':
756 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
758 print "Can not find system boost libraries with version %s " % boost_version
759 print "Please supply a path through extra_lib_path and try again."
760 print "Or use boost=included to use included boost libraries."
763 included_boost = False
764 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
765 env_cache['BOOST_LIBRARIES'] = boost_libraries
766 env_cache['INCLUDED_BOOST'] = included_boost
767 env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
768 env_cache['BOOST_LIBPATH'] = boost_libpath
770 boost_libraries = env_cache['BOOST_LIBRARIES']
771 included_boost = env_cache['INCLUDED_BOOST']
772 env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
773 boost_libpath = env_cache['BOOST_LIBPATH']
775 if boost_libpath is not None:
776 env.AppendUnique(LIBPATH = [boost_libpath])
779 env['ENABLE_NLS'] = env['nls']
782 if not env['ENABLE_NLS']:
784 included_gettext = False
786 # check gettext libraries
787 gettext_opt = ARGUMENTS.get('gettext', 'auto')
788 # check for system gettext
790 if gettext_opt in ['auto', 'system']:
791 if conf.CheckLib('intl'):
792 included_gettext = False
796 if gettext_opt == 'system':
797 print "Can not find system gettext library"
798 print "Please supply a path through extra_lib_path and try again."
799 print "Or use gettext=included to use included gettext libraries."
801 # now, auto and succ = false, or gettext=included
803 # we do not need to set LIBPATH now.
804 included_gettext = True
805 intl_libs = ['included_intl']
806 env_cache['INCLUDED_GETTEXT'] = included_gettext
807 env_cache['INTL_LIBS'] = intl_libs
809 included_gettext = env_cache['INCLUDED_GETTEXT']
810 intl_libs = env_cache['INTL_LIBS']
813 # check for msgfmt command
815 env['MSGFMT'] = conf.CheckCommand('msgfmt')
816 env_cache['MSGFMT'] = env['MSGFMT']
818 env['MSGFMT'] = env_cache['MSGFMT']
820 # check uic and moc commands for qt frontends
822 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
823 or conf.CheckCommand('moc') == None):
824 print 'uic or moc command is not found for frontend', frontend
828 # Customized builders
830 # install customized builders
831 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
834 #----------------------------------------------------------
835 # Generating config.h
836 #----------------------------------------------------------
837 aspell_lib = 'aspell'
838 # assume that we use aspell, aspelld compiled for msvc
839 if platform_name == 'win32' and mode == 'debug' and use_vc:
840 aspell_lib = 'aspelld'
842 # check the existence of config.h
843 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
844 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
845 if not fast_start or not os.path.isfile(boost_config_h) \
846 or not os.path.isfile(config_h):
848 print "Creating %s..." % boost_config_h
850 utils.createConfigFile(conf,
851 config_file = boost_config_h,
852 config_pre = '''/* boost/config.h. Generated by SCons. */
857 * This file is part of LyX, the document processor.
858 * Licence details can be found in the file COPYING.
860 * This is the compilation configuration file for LyX.
861 * It was generated by scon.
862 * You might want to change some of the defaults if something goes wrong
863 * during the compilation.
866 #ifndef _BOOST_CONFIG_H
867 #define _BOOST_CONFIG_H
870 ('ostream', 'HAVE_OSTREAM', 'cxx'),
871 ('locale', 'HAVE_LOCALE', 'cxx'),
872 ('sstream', 'HAVE_SSTREAM', 'cxx'),
873 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
876 (env.has_key('assertions') and env['assertions'],
878 'Define if you want assertions to be enabled in the code'
883 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
884 # define USE_BOOST_FORMAT 1
886 # define USE_BOOST_FORMAT 0
889 #if !defined(ENABLE_ASSERTIONS)
890 # define BOOST_DISABLE_ASSERTS 1
892 #define BOOST_ENABLE_ASSERT_HANDLER 1
894 #define BOOST_DISABLE_THREADS 1
895 #define BOOST_NO_WREGEX 1
896 #define BOOST_NO_WSTRING 1
899 # define BOOST_POSIX 1
902 #define BOOST_ALL_NO_LIB 1
904 #if defined(HAVE_NEWAPIS_H)
905 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
912 print "\nGenerating %s..." % config_h
914 # AIKSAURUS_H_LOCATION
915 if (conf.CheckCXXHeader("Aiksaurus.h")):
916 aik_location = '<Aiksaurus.h>'
917 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
918 aik_location = '<Aiksaurus/Aiksaurus.h>'
922 # determine headers to use
923 spell_opt = ARGUMENTS.get('spell', 'auto')
924 env['USE_ASPELL'] = False
925 env['USE_PSPELL'] = False
926 env['USE_ISPELL'] = False
927 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
928 spell_engine = 'USE_ASPELL'
929 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
930 spell_engine = 'USE_PSPELL'
931 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
932 spell_engine = 'USE_ISPELL'
936 if spell_engine is not None:
937 env[spell_engine] = True
939 if spell_opt == 'auto':
940 print "Warning: Can not locate any spell checker"
941 elif spell_opt != 'no':
942 print "Warning: Can not locate specified spell checker:", spell_opt
945 # check arg types of select function
946 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
950 result = utils.createConfigFile(conf,
951 config_file = config_h,
952 config_pre = '''/* config.h. Generated by SCons. */
957 * This file is part of LyX, the document processor.
958 * Licence details can be found in the file COPYING.
960 * This is the compilation configuration file for LyX.
961 * It was generated by scon.
962 * You might want to change some of the defaults if something goes wrong
963 * during the compilation.
970 ('io.h', 'HAVE_IO_H', 'c'),
971 ('limits.h', 'HAVE_LIMITS_H', 'c'),
972 ('locale.h', 'HAVE_LOCALE_H', 'c'),
973 ('process.h', 'HAVE_PROCESS_H', 'c'),
974 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
975 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
976 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
977 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
978 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
979 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
980 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
981 ('utime.h', 'HAVE_UTIME_H', 'c'),
982 ('direct.h', 'HAVE_DIRECT_H', 'c'),
983 ('istream', 'HAVE_ISTREAM', 'cxx'),
984 ('ios', 'HAVE_IOS', 'cxx'),
987 ('open', 'HAVE_OPEN', None),
988 ('close', 'HAVE_CLOSE', None),
989 ('popen', 'HAVE_POPEN', None),
990 ('pclose', 'HAVE_PCLOSE', None),
991 ('_open', 'HAVE__OPEN', None),
992 ('_close', 'HAVE__CLOSE', None),
993 ('_popen', 'HAVE__POPEN', None),
994 ('_pclose', 'HAVE__PCLOSE', None),
995 ('getpid', 'HAVE_GETPID', None),
996 ('_getpid', 'HAVE__GETPID', None),
997 ('mkdir', 'HAVE_MKDIR', None),
998 ('_mkdir', 'HAVE__MKDIR', None),
999 ('mktemp', 'HAVE_MKTEMP', None),
1000 ('mkstemp', 'HAVE_MKSTEMP', None),
1001 ('strerror', 'HAVE_STRERROR', None),
1002 ('count', 'HAVE_STD_COUNT', '''
1003 #include <algorithm>
1007 return std::count(a, a+5, 'l');
1010 ('getcwd', 'HAVE_GETCWD', None),
1011 ('setenv', 'HAVE_SETENV', None),
1012 ('putenv', 'HAVE_PUTENV', None),
1013 ('fcntl', 'HAVE_FCNTL', None),
1016 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1017 '#include <streambuf>\n#include <istream>')
1020 ('gdi32', 'HAVE_LIBGDI32'),
1021 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1022 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1025 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1027 'Define is sys/types.h does not have pid_t',
1029 '#define pid_t int',
1031 (conf.CheckCXXGlobalCstd(),
1033 'Define if your C++ compiler puts C library functions in the global namespace'
1035 (conf.CheckMkdirOneArg(),
1036 'MKDIR_TAKES_ONE_ARG',
1037 'Define if mkdir takes only one argument.'
1039 (conf.CheckLC_MESSAGES(),
1041 'Define if your <locale.h> file defines LC_MESSAGES.'
1043 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1046 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1048 (env['nls'] and not included_gettext,
1050 'Define to 1 if using system gettext library'
1052 (env.has_key('warnings') and env['warnings'],
1054 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1056 (env.has_key('concept_checks') and env['concept_checks'],
1057 '_GLIBCXX_CONCEPT_CHECKS',
1058 'libstdc++ concept checking'
1060 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1062 'libstdc++ debug mode'
1064 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1065 '_GLIBCXX_DEBUG_PEDANTIC',
1066 'libstdc++ pedantic debug mode'
1068 (os.name != 'nt', 'BOOST_POSIX',
1069 'Indicates to boost which API to use (posix or windows).'
1071 (spell_engine is not None, spell_engine,
1072 'Spell engine to use'
1076 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1078 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1079 'Define to the address where bug reports for this package should be sent.'),
1080 ('#define PACKAGE_NAME "%s"' % package_name,
1081 'Define to the full name of this package.'),
1082 ('#define PACKAGE_STRING "%s"' % package_string,
1083 'Define to the full name and version of this package.'),
1084 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1085 'Define to the one symbol short name of this package.'),
1086 ('#define PACKAGE_VERSION "%s"' % package_version,
1087 'Define to the version of this package.'),
1088 ('#define BOOST_ALL_NO_LIB 1',
1089 'disable automatic linking of boost libraries.'),
1090 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1091 'Packaging method'),
1092 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1093 'Aiksaurus include file'),
1094 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1095 "Define to the type of arg 1 for `select'."),
1096 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1097 "Define to the type of arg 2, 3, 4 for `select'."),
1098 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1099 "Define to the type of arg 5 for `select'."),
1101 config_post = '''/************************************************************
1102 ** You should not need to change anything beyond this point */
1104 #ifndef HAVE_STRERROR
1105 #if defined(__cplusplus)
1108 char * strerror(int n);
1112 #ifndef HAVE_DECL_MKSTEMP
1113 #if defined(__cplusplus)
1120 #include <../boost/config.h>
1126 # these keys are needed in env
1127 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1128 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1129 'ICONV_LIB', 'AIKSAURUS_LIB']:
1130 # USE_ASPELL etc does not go through result
1131 if result.has_key(key):
1132 env[key] = result[key]
1133 env_cache[key] = env[key]
1136 # if nls=yes and gettext=included, create intl/config.h
1137 # intl/libintl.h etc
1139 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1140 if env['nls'] and included_gettext:
1142 print "Creating %s..." % intl_config_h
1144 # create intl/config.h
1145 result = utils.createConfigFile(conf,
1146 config_file = intl_config_h,
1147 config_pre = '''/* intl/config.h. Generated by SCons. */
1152 * This file is part of LyX, the document processor.
1153 * Licence details can be found in the file COPYING.
1155 * This is the compilation configuration file for LyX.
1156 * It was generated by scon.
1157 * You might want to change some of the defaults if something goes wrong
1158 * during the compilation.
1165 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1166 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1167 ('string.h', 'HAVE_STRING_H', 'c'),
1168 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1169 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1170 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1171 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1172 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1173 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1174 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1177 ('getcwd', 'HAVE_GETCWD', None),
1178 ('stpcpy', 'HAVE_STPCPY', None),
1179 ('strcasecmp', 'HAVE_STRCASECMP', None),
1180 ('strdup', 'HAVE_STRDUP', None),
1181 ('strtoul', 'HAVE_STRTOUL', None),
1182 ('alloca', 'HAVE_ALLOCA', None),
1183 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1184 ('mempcpy', 'HAVE_MEMPCPY', None),
1185 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1186 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1187 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1188 ('setlocale', 'HAVE_SETLOCALE', None),
1189 ('tsearch', 'HAVE_TSEARCH', None),
1190 ('getegid', 'HAVE_GETEGID', None),
1191 ('getgid', 'HAVE_GETGID', None),
1192 ('getuid', 'HAVE_GETUID', None),
1193 ('wcslen', 'HAVE_WCSLEN', None),
1194 ('asprintf', 'HAVE_ASPRINTF', None),
1195 ('wprintf', 'HAVE_WPRINTF', None),
1196 ('snprintf', 'HAVE_SNPRINTF', None),
1197 ('printf', 'HAVE_POSIX_PRINTF', None),
1198 ('fcntl', 'HAVE_FCNTL', None),
1201 ('intmax_t', 'HAVE_INTMAX_T', None),
1202 ('long double', 'HAVE_LONG_DOUBLE', None),
1203 ('long long', 'HAVE_LONG_LONG', None),
1204 ('wchar_t', 'HAVE_WCHAR_T', None),
1205 ('wint_t', 'HAVE_WINT_T', None),
1206 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1207 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1210 (('iconv', 'libiconv'), 'HAVE_ICONV', 'ICONV_LIB'),
1214 (conf.CheckLC_MESSAGES(),
1216 'Define if your <locale.h> file defines LC_MESSAGES.'
1218 (conf.CheckIconvConst(),
1220 'Define as const if the declaration of iconv() needs const.',
1221 '#define ICONV_CONST',
1222 '#define ICONV_CONST const',
1224 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1225 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1227 "Define to 1 if you have the `intmax_t' type."
1229 (env.has_key('nls') and env['nls'],
1231 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1234 config_post = '#endif'
1237 # these keys are needed in env
1238 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1239 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1240 # USE_ASPELL etc does not go through result
1241 if result.has_key(key):
1242 env[key] = result[key]
1243 env_cache[key] = env[key]
1247 # this comes as a big surprise, without this line
1248 # (doing nothing obvious), adding fast_start=yes
1249 # to a build with fast_start=no will result in a rebuild
1250 # Note that the exact header file to check does not matter
1251 conf.CheckCHeader('io.h')
1252 # only a few variables need to be rescanned
1253 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1254 'HAVE_ICONV', 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS',
1255 'ICONV_LIB', 'AIKSAURUS_LIB']:
1256 env[key] = env_cache[key]
1259 if env['nls'] and included_gettext:
1260 # only a few variables need to be rescanned
1261 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1262 'HAVE_POSIX_PRINTF', 'HAVE_ICONV', 'HAVE_LIBC']:
1263 env[key] = env_cache[key]
1265 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1266 if env['nls'] and included_gettext:
1267 # libgnuintl.h.in => libintl.h
1268 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1269 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1270 [Copy('$TARGET', '$SOURCE')])
1273 # Finish auto-configuration
1276 #----------------------------------------------------------
1277 # Now set up our build process accordingly
1278 #----------------------------------------------------------
1283 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1284 # in their respective directory and specialized env.
1285 if frontend == 'qt3':
1286 # note: env.Tool('qt') my set QT_LIB to qt
1288 frontend_libs = ['qt-mt']
1289 elif frontend == 'qt4':
1290 qt_libs = ['QtCore', 'QtGui']
1291 # set the right lib names
1292 if platform_name == 'win32':
1293 if mode == 'debug' and use_vc:
1294 qt_lib_suffix = 'd4'
1299 qt_lib_suffix = '_debug'
1302 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1305 if platform_name in ['win32', 'cygwin']:
1306 # the final link step needs stdc++ to succeed under mingw
1307 # FIXME: shouldn't g++ automatically link to stdc++?
1309 system_libs = ['shlwapi', 'shell32', 'advapi32', 'zdll']
1311 system_libs = ['shlwapi', 'stdc++', 'z']
1312 elif platform_name == 'cygwin' and env['X11']:
1313 system_libs = ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr', 'Xcursor',
1314 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE', 'resolv',
1320 ('HAVE_ICONV', env['ICONV_LIB']),
1321 ('HAVE_LIBGDI32', 'gdi32'),
1322 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1323 ('USE_ASPELL', aspell_lib),
1324 ('USE_ISPELL', 'ispell'),
1325 ('USE_PSPELL', 'pspell'),
1330 system_libs.append(lib[1])
1333 # Build parameters CPPPATH etc
1336 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1339 # boost: for boost header files
1340 # BUILDDIR/common: for config.h
1341 # TOP_SRCDIR/src: for support/* etc
1343 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1345 # Separating boost directories from CPPPATH stops scons from building
1346 # the dependency tree for boost header files, and effectively reduce
1347 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1348 # boost headers, this is only done for system boost headers.
1350 env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1353 env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1355 env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1357 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1358 if env['nls'] and included_gettext:
1359 env['CPPPATH'].append('$BUILDDIR/intl')
1361 # QT_INC_PATH is not needed for *every* source file
1362 env['CPPPATH'].remove(qt_inc_path)
1365 # A Link script for cygwin see
1366 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1367 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1370 if platform_name == 'cygwin':
1371 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1372 ld_script = utils.installCygwinLDScript(ld_script_path)
1373 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1374 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1379 # fill in the version info
1380 env['VERSION_INFO'] = '''Configuration
1382 Special build flags: %s
1384 C Compiler flags: %s %s
1386 C++ Compiler LyX flags: %s
1387 C++ Compiler flags: %s %s
1389 Linker user flags: %s
1391 Builing directory: %s
1392 Local library directory: %s
1395 Frontend libraries: %s
1396 System libraries: %s
1397 include search path: %s
1403 ''' % (platform_name,
1404 env.subst('$CCFLAGS'), env.subst('$CC'),
1405 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1406 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1407 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1408 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1409 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1410 str(env['LIBPATH']), str(boost_libraries),
1411 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1412 frontend, packaging_method,
1413 prefix, env['LYX_DIR'])
1415 if frontend in ['qt3', 'qt4']:
1416 env['VERSION_INFO'] += ''' include dir: %s
1419 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1422 print env['VERSION_INFO']
1425 # Mingw command line may be too short for our link usage,
1426 # Here we use a trick from scons wiki
1427 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1429 # I also would like to add logging (commands only) capacity to the
1431 logfile = env.get('logfile', default_log_file)
1432 if logfile != '' or platform_name == 'win32':
1434 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1435 info = '''# This is a log of commands used by scons to build lyx
1439 ''' % (time.asctime(), ' '.join(sys.argv),
1440 env['VERSION_INFO'].replace('\n','\n# ')) )
1445 # -h will print out help info
1446 Help(opts.GenerateHelpText(env))
1448 # save environment settings (for fast_start option)
1449 cache_file = open(env_cache_file, 'w')
1450 cPickle.dump(env_cache, cache_file)
1454 #----------------------------------------------------------
1456 #----------------------------------------------------------
1457 # this has been the source of problems on some platforms...
1458 # I find that I need to supply it with full path name
1459 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1460 # this usage needs further investigation.
1461 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1463 print "Building all targets recursively"
1465 if env.has_key('rebuild'):
1466 rebuild_targets = env['rebuild'].split(',')
1467 if 'none' in rebuild_targets or 'no' in rebuild_targets:
1468 rebuild_targets = []
1469 elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1470 # None: let scons decide which components to build
1471 # Forcing all components to be rebuilt is in theory not necessary
1472 rebuild_targets = None
1474 rebuild_targets = None
1476 def libExists(libname):
1477 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1478 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1480 def appExists(apppath, appname):
1481 ''' Check whether or not application already exists'''
1482 return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1484 targets = BUILD_TARGETS
1485 # msvc need to pass full target name, so I have to look for path/lyx etc
1486 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1487 or 'install' in targets or 'all' in targets
1488 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1489 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1490 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1491 build_mathed = build_lyx or 'mathed' in targets
1492 build_insets = build_lyx or 'insets' in targets
1493 build_frontends = build_lyx or 'frontends' in targets
1494 build_graphics = build_lyx or 'graphics' in targets
1495 build_controllers = build_lyx or 'controllers' in targets
1496 build_client = True in ['client' in x for x in targets] \
1497 or 'install' in targets or 'all' in targets
1498 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1499 or 'install' in targets or 'all' in targets
1500 build_lyxbase = build_lyx or 'lyxbase' in targets
1501 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1502 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1503 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1504 build_msvs_projects = use_vc and 'msvs_projects' in targets
1507 # now, if rebuild_targets is specified, do not rebuild some targets
1508 if rebuild_targets is not None:
1510 def ifBuildLib(name, libname, old_value):
1511 # explicitly asked to rebuild
1512 if name in rebuild_targets:
1514 # else if not rebuild, and if the library already exists
1515 elif libExists(libname):
1517 # do not change the original value
1520 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1521 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1522 build_support = ifBuildLib('support', 'support', build_support)
1523 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1524 build_insets = ifBuildLib('insets', 'insets', build_insets)
1525 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1526 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1527 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1528 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1529 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1530 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1532 def ifBuildApp(name, appname, old_value):
1533 # explicitly asked to rebuild
1534 if name in rebuild_targets:
1536 # else if not rebuild, and if the library already exists
1537 elif appExists(name, appname):
1539 # do not change the original value
1542 build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1543 build_client = ifBuildApp('client', 'lyxclient', build_client)
1545 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1557 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1559 boostenv = env.Copy()
1561 # boost use its own config.h
1562 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1563 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1565 for lib in boost_libs:
1566 print 'Processing files in boost/libs/%s/src...' % lib
1567 boostlib = boostenv.StaticLibrary(
1568 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1569 source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1571 Alias('boost', boostlib)
1578 intlenv = env.Copy()
1580 print "Processing files in intl..."
1582 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1584 # we need the original C compiler for these files
1585 intlenv['CC'] = C_COMPILER
1586 intlenv['CCFLAGS'] = C_CCFLAGS
1588 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1589 # intl does not use global config.h
1590 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1592 intlenv.Append(CCFLAGS = [
1593 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1594 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1595 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1597 '-DENABLE_RELOCATABLE=1',
1599 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1601 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1602 '-Drelocate=libintl_relocate',
1603 '-DDEPENDS_ON_LIBICONV=1',
1608 intl = intlenv.StaticLibrary(
1609 target = '$LOCALLIBPATH/included_intl',
1611 source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1617 # Now, src code under src/
1619 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1626 print "Processing files in src/support..."
1628 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1630 support = env.StaticLibrary(
1631 target = '$LOCALLIBPATH/support',
1632 source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1634 Alias('support', support)
1641 print "Processing files in src/mathed..."
1643 mathed = env.StaticLibrary(
1644 target = '$LOCALLIBPATH/mathed',
1645 source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1647 Alias('mathed', mathed)
1654 print "Processing files in src/insets..."
1656 insets = env.StaticLibrary(
1657 target = '$LOCALLIBPATH/insets',
1658 source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1660 Alias('insets', insets)
1667 print "Processing files in src/frontends..."
1669 frontends = env.StaticLibrary(
1670 target = '$LOCALLIBPATH/frontends',
1671 source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1673 Alias('frontends', frontends)
1680 print "Processing files in src/graphics..."
1682 graphics = env.StaticLibrary(
1683 target = '$LOCALLIBPATH/graphics',
1684 source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1686 Alias('graphics', graphics)
1689 if build_controllers:
1691 # src/frontends/controllers
1693 print "Processing files in src/frontends/controllers..."
1695 controllers = env.StaticLibrary(
1696 target = '$LOCALLIBPATH/controllers',
1697 source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1699 Alias('controllers', controllers)
1703 # src/frontend/qt3/4
1705 if build_qt3 or build_qt4:
1706 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1709 print "Processing files in src/frontends/qt3..."
1712 # disable auto scan to speed up non build time
1713 qt3env['QT_AUTOSCAN'] = 0
1714 qt3env['QT_MOCHPREFIX'] = ''
1719 qt3env.AppendUnique(CPPPATH = [
1721 '$BUILDDIR/common/images',
1722 '$BUILDDIR/common/frontends',
1723 '$BUILDDIR/common/frontends/qt3',
1724 '$BUILDDIR/common/frontends/controllers',
1728 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1730 # manually moc and uic files for better performance
1731 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1733 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1734 src_frontends_qt3_ui_files]
1736 qt3_uiced_cc_files = []
1737 for x in qt3_uiced_files:
1738 qt3_uiced_cc_files.extend(x[1:])
1740 qt3 = qt3env.StaticLibrary(
1741 target = '$LOCALLIBPATH/qt3',
1742 source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1743 + qt3_moced_files + qt3_uiced_cc_files
1749 print "Processing files in src/frontends/qt4..."
1752 qt4env['QT_AUTOSCAN'] = 0
1754 # local qt4 toolset from
1755 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1757 # NOTE: I have to patch qt4.py since it does not automatically
1758 # process .C file!!! (add to cxx_suffixes )
1760 qt4env.Tool('qt4', [scons_dir])
1761 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1763 qt4env.AppendUnique(CPPPATH = [
1765 '$BUILDDIR/common/images',
1766 '$BUILDDIR/common/frontends',
1767 '$BUILDDIR/common/frontends/qt4',
1768 '$BUILDDIR/common/frontends/controllers',
1773 # FIXME: replace by something from pkg_config
1774 qt4env.Append(CCFLAGS = [
1776 '-DQT_CLEAN_NAMESPACE',
1785 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1790 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1791 src_frontends_qt4_ui_files]
1794 # moc qt4_moc_files, the moced files are included in the original files
1796 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1798 qt4 = qt4env.StaticLibrary(
1799 target = '$LOCALLIBPATH/qt4',
1800 source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1809 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1811 print "Processing files in src/client..."
1813 if env['HAVE_FCNTL']:
1814 client = env.Program(
1815 target = '$BUILDDIR/common/client/lyxclient',
1816 LIBS = ['support'] + intl_libs + system_libs +
1817 socket_libs + boost_libraries,
1818 source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1820 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1821 client, [Copy('$TARGET', '$SOURCE')]))
1824 Alias('client', client)
1826 if env['HAVE_FCNTL']:
1827 # define client even if lyxclient is not built with rebuild=no
1828 client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1837 print "Processing files in src/tex2lyx..."
1839 tex2lyx_env = env.Copy()
1841 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1842 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1844 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1845 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1846 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1847 [Copy('$TARGET', '$SOURCE')])
1849 tex2lyx = tex2lyx_env.Program(
1850 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1851 LIBS = ['support'] + boost_libraries + system_libs,
1852 source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1854 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1855 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1856 Alias('tex2lyx', tex2lyx)
1858 # define tex2lyx even if tex2lyx is not built with rebuild=no
1859 tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1866 print "Processing files in src..."
1868 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1870 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1871 lyx_post_source.append('aspell.C')
1872 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1873 lyx_post_source.append('pspell.C')
1874 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1875 lyx_post_source.append('ispell.C')
1877 # msvc requires at least one source file with main()
1878 # so I exclude main.C from lyxbase
1879 lyxbase_pre = env.StaticLibrary(
1880 target = '$LOCALLIBPATH/lyxbase_pre',
1881 source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1883 lyxbase_post = env.StaticLibrary(
1884 target = '$LOCALLIBPATH/lyxbase_post',
1885 source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1887 Alias('lyxbase', lyxbase_pre)
1888 Alias('lyxbase', lyxbase_post)
1893 # Build lyx with given frontend
1896 target = '$BUILDDIR/$frontend/lyx',
1897 source = ['$BUILDDIR/common/main.C'],
1915 # [/path/to/lyx.ext] => lyx-qt3.ext
1916 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1917 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1918 [Copy('$TARGET', '$SOURCE')]))
1921 # define lyx even if lyx is not built with rebuild=no
1922 lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1925 if build_msvs_projects:
1926 def build_project(target, full_target = None,
1927 src = [], inc = [], res = [], rebuildTargetOnly = True):
1928 ''' build mavs project files
1929 target: alias (correspond to directory name)
1930 full_target: full path/filename of the target
1934 rebuildTargetOnly: whether or not only rebuild this target
1936 For non-debug-able targets like static libraries, target (alias) is
1937 enough to build the target. For executable targets, msvs need to know
1938 the full path to start debug them.
1940 if rebuildTargetOnly:
1941 cmds = 'fast_start=yes rebuild='+target
1943 cmds = 'fast_start=yes'
1944 if full_target is None:
1945 build_target = target
1947 build_target = full_target
1949 proj = env.MSVSProject(
1950 target = target + env['MSVSPROJECTSUFFIX'],
1951 # this allows easy access to header files (along with source)
1952 srcs = [env.subst(x) for x in src + inc],
1953 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
1954 localincs = [env.subst(x) for x in inc],
1955 resources = [env.subst(x) for x in res],
1956 buildtarget = build_target,
1960 Alias('msvs_projects', proj)
1963 for lib in boost_libs:
1964 boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1965 build_project('boost', src = boost_src)
1967 build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files],
1968 inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
1970 build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
1971 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
1973 build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
1974 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
1976 build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files],
1977 inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
1979 build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files],
1980 inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
1982 build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files],
1983 inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
1985 build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files],
1986 inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
1988 build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
1989 inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
1990 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
1992 build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
1993 inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
1994 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
1996 build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
1997 inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
1998 rebuildTargetOnly = False,
1999 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2001 build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2002 inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2003 rebuildTargetOnly = False,
2004 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2006 build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2007 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2009 if frontend == 'qt3':
2010 build_project('lyx',
2011 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2012 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2013 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2014 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2015 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2016 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2017 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2018 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2019 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2020 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2021 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2022 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2023 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2024 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2025 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2026 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2027 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2028 rebuildTargetOnly = False,
2029 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2031 build_project('lyx',
2032 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2033 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2034 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2035 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2036 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2037 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2038 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2039 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2040 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2041 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2042 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2043 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2044 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2045 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2046 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2047 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2048 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2049 rebuildTargetOnly = False,
2050 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2057 print 'Processing files in po...'
2062 # files to translate
2063 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2064 # possibly *only* handle these languages
2066 if env.has_key('languages'):
2067 languages = env.make_list(env['lanauges'])
2068 # use defulat msgfmt
2070 if not env['MSGFMT']:
2071 print 'msgfmt does not exist. Can not process po files'
2074 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2076 for f in transfiles:
2078 fname = os.path.split(f)[1]
2080 country = fname.split('.')[0]
2082 if not languages or country in languages:
2083 gmo_files.extend(env.Transfiles(f))
2086 if 'install' in targets:
2088 # this part is a bit messy right now. Since scons will provide
2089 # --DESTDIR option soon, at least the dest_dir handling can be
2092 # how to join dest_dir and prefix
2093 def joinPaths(path1, path2):
2094 ''' join path1 and path2, do not use os.path.join because
2095 under window, c:\destdir\d:\program is invalid '''
2097 return os.path.normpath(path2)
2098 # separate drive letter
2099 (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2100 # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2101 return os.path.join(os.path.normpath(path1), path[1:])
2103 # install to dest_dir/prefix
2104 dest_dir = env.get('DESTDIR', None)
2105 dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2106 # create the directory if needed
2107 if not os.path.isdir(dest_prefix_dir):
2109 os.makedirs(dest_prefix_dir)
2112 if not os.path.isdir(dest_prefix_dir):
2113 print 'Can not create directory', dest_prefix_dir
2116 if env.has_key('exec_prefix'):
2117 bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2119 bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2121 share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2123 share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2124 man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2125 locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2129 # install executables (lyxclient may be None)
2132 version_suffix = program_suffix
2137 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2138 target = os.path.join(bin_dest_dir, target_name)
2139 env.InstallAs(target, lyx)
2140 Alias('install', target)
2141 # install lyx as lyx-qt3
2142 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2143 target = os.path.join(bin_dest_dir, target_name)
2144 env.InstallAs(target, lyx)
2145 Alias('install', target)
2148 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2149 target = os.path.join(bin_dest_dir, target_name)
2150 env.InstallAs(target, tex2lyx)
2151 Alias('install', target)
2153 # install lyxclient, may not exist
2155 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2156 target = os.path.join(bin_dest_dir, target_name)
2157 env.InstallAs(target, client)
2158 Alias('install', target)
2162 for (dir,files) in [
2164 ('clipart', lib_clipart_files),
2165 ('examples', lib_examples_files),
2166 ('images', lib_images_files),
2167 ('images/math', lib_images_math_files),
2168 ('bind', lib_bind_files),
2169 ('kbd', lib_kbd_files),
2170 ('layouts', lib_layouts_files),
2171 ('scripts', lib_scripts_files),
2172 ('templates', lib_templates_files),
2173 ('tex', lib_tex_files),
2174 ('ui', lib_ui_files),
2175 ('doc', lib_doc_files),
2176 ('lyx2lyx', lib_lyx2lyx_files)]:
2177 dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2178 [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2180 # lyx1.4.x does not have lyx2lyx_version.py.in
2181 if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2182 # subst and install this file
2183 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2184 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2185 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2186 Alias('install', dirs)
2188 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2189 env.subst('$TOP_SRCDIR/lyx.man'))
2190 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2191 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2192 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2193 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2194 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2195 x in ['lyx', 'tex2lyx', 'lyxclient']])
2197 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2198 for gmo in gmo_files:
2199 lan = os.path.split(str(gmo))[1].split('.')[0]
2200 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
2201 env.InstallAs(dest_file, gmo)
2202 Alias('install', dest_file)
2206 Alias('all', ['lyx', 'client', 'tex2lyx'])