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'
63 package_bugreport = 'lyx-devel@lists.lyx.org'
65 package_tarname = 'lyx'
66 package_string = '%s %s' % (package_name, package_version)
68 # various cache/log files
69 default_log_file = 'scons_lyx.log'
70 env_cache_file = 'env.cache'
73 #----------------------------------------------------------
74 # platform dependent settings
75 #----------------------------------------------------------
78 platform_name = 'win32'
79 default_frontend = 'qt4'
80 default_prefix = 'c:/program files/lyx'
81 default_with_x = False
82 default_packaging_method = 'windows'
83 elif os.name == 'posix' and sys.platform != 'cygwin':
84 platform_name = sys.platform
85 default_frontend = 'qt3'
86 default_prefix = '/usr/local'
88 default_packaging_method = 'posix'
89 elif os.name == 'posix' and sys.platform == 'cygwin':
90 platform_name = 'cygwin'
91 default_frontend = 'qt3'
92 default_prefix = '/usr'
94 default_packaging_method = 'posix'
95 elif os.name == 'darwin':
96 platform_name = 'macosx'
97 default_frontend = 'qt3'
98 # FIXME: macOSX default prefix?
100 default_with_x = False
101 default_packaging_method = 'macosx'
102 else: # unsupported system, assume posix behavior
103 platform_name = 'others'
104 default_frontend = 'qt3'
106 default_with_x = True
107 default_packaging_method = 'posix'
109 #---------------------------------------------------------
111 #----------------------------------------------------------
113 # You can set perminant default values in config.py
114 if os.path.isfile('config.py'):
115 print "Getting options from config.py..."
116 print open('config.py').read()
118 opts = Options(['config.py'])
121 EnumOption('frontend', 'Main GUI', default_frontend,
122 allowed_values = ('qt3', 'qt4', 'gtk') ),
123 # debug or release build
124 EnumOption('mode', 'Building method', default_build_mode,
125 allowed_values = ('debug', 'release') ),
128 'Use included, system boost library, or try sytem boost first.',
129 'auto', allowed_values = (
130 'auto', # detect boost, if not found, use included
131 'included', # always use included boost
132 'system', # always use system boost, fail if can not find
135 EnumOption('gettext',
136 'Use included, system gettext library, or try sytem gettext first',
137 'auto', allowed_values = (
138 'auto', # detect gettext, if not found, use included
139 'included', # always use included gettext
140 'system', # always use system gettext, fail if can not find
143 EnumOption('spell', 'Choose spell checker to use.', 'auto',
144 allowed_values = ('aspell', 'pspell', 'ispell', 'auto', 'no') ),
146 EnumOption('packaging', 'Packaging method to use.', default_packaging_method,
147 allowed_values = ('windows', 'posix', 'macosx')),
149 BoolOption('fast_start', 'Whether or not use cached tests and keep current config.h', True),
150 # No precompiled header support (too troublesome to make it work for msvc)
151 # BoolOption('pch', 'Whether or not use pch', False),
152 # enable assertion, (config.h has ENABLE_ASSERTIOS
153 BoolOption('assertions', 'Use assertions', True),
154 # enable warning, (config.h has WITH_WARNINGS)
155 # default to False since MSVC does not have #warning
156 BoolOption('warnings', 'Use warnings', False),
157 # config.h define _GLIBCXX_CONCEPT_CHECKS
158 # Note: for earlier version of gcc (3.3) define _GLIBCPP_CONCEPT_CHECKS
159 BoolOption('concept_checks', 'Enable concept checks', True),
161 BoolOption('nls', 'Whether or not use native language support', True),
163 BoolOption('profiling', 'Whether or not enable profiling', False),
164 # config.h define _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC
165 BoolOption('stdlib_debug', 'Whether or not turn on stdlib debug', False),
167 BoolOption('X11', 'Use x11 windows system', default_with_x),
168 # use MS VC++ to build lyx
169 BoolOption('use_vc', 'Use MS VC++ to build lyx (cl.exe will be probed)', None),
171 PathOption('qt_dir', 'Path to qt directory', None),
173 PathOption('qt_inc_path', 'Path to qt include directory', None),
175 PathOption('qt_lib_path', 'Path to qt library 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.
188 yes or all (default): rebuild everything
189 no or none: rebuild nothing (usually used for installation)
190 comp1,comp2,...: rebuild specified targets''', None),
191 # can be set to a non-existing directory
192 ('prefix', 'install architecture-independent files in PREFIX', default_prefix),
193 # build directory, will use $mode if not set
194 ('build_dir', 'Build directory', None),
196 ('version_suffix', 'install lyx as lyx-suffix', None),
197 # how to load options
198 ('load_option', '''load option from previous scons run. option can be
199 yes (default): load all options
200 no: do not load any option
201 opt1,opt2: load specified options
202 -opt1,opt2: load all options other than specified ones''', 'yes'),
204 ('optimization', 'optimization CCFLAGS option.', None),
206 PathOption('exec_prefix', 'install architecture-independent executable files in PREFIX', None),
208 ('logfile', 'save commands (not outputs) to logfile', default_log_file),
209 # provided for backward compatibility
210 ('dest_dir', 'install to DESTDIR. (Provided for backward compatibility only)', None),
211 # environment variable can be set as options.
212 ('DESTDIR', 'install to DESTDIR', None),
213 ('CC', 'replace default $CC', None),
214 ('LINK', 'replace default $LINK', None),
215 ('CPP', 'replace default $CPP', None),
216 ('CXX', 'replace default $CXX', None),
217 ('CXXCPP', 'replace default $CXXCPP', None),
218 ('CCFLAGS', 'replace default $CCFLAGS', None),
219 ('CPPFLAGS', 'replace default $CPPFLAGS', None),
220 ('LINKFLAGS', 'replace default $LINKFLAGS', None),
224 all_options = [x.key for x in opts.options]
226 # copied from SCons/Options/BoolOption.py
227 # We need to use them before a boolean ARGUMENTS option is available
229 true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
230 false_strings = ('n', 'no', 'false', 'f', '0', 'off', 'none')
232 # whether or not use current config.h, and cached tests
234 # if fast_start=yes (default), load variables from env_cache_file
235 if (not ARGUMENTS.has_key('fast_start') or \
236 ARGUMENTS['fast_start'] in true_strings) \
237 and os.path.isfile(env_cache_file):
239 cache_file = open(env_cache_file)
240 env_cache = cPickle.load(cache_file)
242 print '------------ fast_start mode --------------------'
243 print ' Use cached test results and current config.h'
244 print ' use fast_start=no to override'
250 # if load_option=yes (default), load saved comand line options
252 # This option can take value yes/no/opt1,opt2/-opt1,opt2
253 # and tries to be clever in choosing options to load
254 if (not ARGUMENTS.has_key('load_option') or \
255 ARGUMENTS['load_option'] not in false_strings) \
256 and os.path.isfile(env_cache_file):
257 cache_file = open(env_cache_file)
258 opt_cache = cPickle.load(cache_file)['arg_cache']
260 # import cached options, but we should ignore qt_dir when frontend changes
261 if ARGUMENTS.has_key('frontend') and opt_cache.has_key('frontend') \
262 and ARGUMENTS['frontend'] != opt_cache['frontend'] \
263 and opt_cache.has_key('qt_dir'):
264 opt_cache.pop('qt_dir')
265 # some options will require full rebuild
266 # these are in general things that will change config.h
267 for arg in ['version_suffix', 'nls', 'boost', 'spell']:
268 if ARGUMENTS.has_key(arg) and ((not opt_cache.has_key(arg)) or \
269 ARGUMENTS[arg] != opt_cache[arg]):
271 print " ** fast_start is disabled because of the change of option", arg
274 # and we do not cache some options (dest_dir is obsolete)
275 for arg in ['fast_start', 'load_option', 'dest_dir']:
276 if opt_cache.has_key(arg):
278 # remove obsolete cached keys (well, SConstruct is evolving. :-)
279 for arg in opt_cache.keys():
280 if arg not in all_options:
281 print 'Option %s is obsolete, do not load it' % arg
283 # now, if load_option=opt1,opt2 or -opt1,opt2
284 if ARGUMENTS.has_key('load_option') and \
285 ARGUMENTS['load_option'] not in true_strings + false_strings:
286 # if -opt1,opt2 is specified, do not load these options
287 if ARGUMENTS['load_option'][0] == '-':
288 for arg in ARGUMENTS['load_option'][1:].split(','):
289 if opt_cache.has_key(arg):
291 # if opt1,opt2 is specified, only load specified options
293 args = ARGUMENTS['load_option'].split(',')
294 for arg in opt_cache.keys():
297 # now restore options as if entered from command line
298 for key in opt_cache.keys():
299 if not ARGUMENTS.has_key(key):
300 ARGUMENTS[key] = opt_cache[key]
301 print "Restoring cached option %s=%s" % (key, ARGUMENTS[key])
304 # check if there is unused (or misspelled) argument
305 for arg in ARGUMENTS.keys():
306 if arg not in all_options:
308 print "Unknown option '%s'... exiting." % arg
310 print "Available options are (check 'scons -help' for details):"
311 print ' ' + '\n '.join(textwrap.wrap(', '.join(all_options)))
315 env_cache['arg_cache'] = ARGUMENTS
318 #---------------------------------------------------------
319 # Setting up environment
320 #---------------------------------------------------------
322 # I do not really like ENV=os.environ, but you may add it
323 # here if you experience some environment related problem
324 env = Environment(options = opts)
326 # set individual variables since I do not really like ENV = os.environ
327 env['ENV']['PATH'] = os.environ.get('PATH')
328 env['ENV']['HOME'] = os.environ.get('HOME')
329 # these are defined for MSVC
330 env['ENV']['LIB'] = os.environ.get('LIB')
331 env['ENV']['INCLUDE'] = os.environ.get('INCLUDE')
333 # for simplicity, use var instead of env[var]
334 frontend = env['frontend']
335 prefix = env['prefix']
338 if platform_name == 'win32':
339 if env.has_key('use_vc'):
340 use_vc = env['use_vc']
341 if WhereIs('cl.exe') is None:
342 print "cl.exe is not found. Are you using the MSVC environment?"
344 elif WhereIs('cl.exe') is not None:
351 # lyx will be built to $build/build_dir so it is possible
352 # to build multiple build_dirs using the same source
353 # $mode can be debug or release
354 if env.has_key('build_dir') and env['build_dir'] is not None:
355 # create the directory if needed
356 if not os.path.isdir(env['build_dir']):
358 os.makedirs(env['build_dir'])
361 if not os.path.isdir(env['build_dir']):
362 print 'Can not create directory', env['build_dir']
364 env['BUILDDIR'] = env['build_dir']
366 # Determine the name of the build $mode
367 env['BUILDDIR'] = '#' + mode
369 # all built libraries will go to build_dir/libs
370 # (This is different from the make file approach)
371 env['LOCALLIBPATH'] = '$BUILDDIR/libs'
372 env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
375 # Here is a summary of variables defined in env
377 # 2. undefined options with a non-None default value
378 # 3. compiler commands and flags like CCFLAGS.
379 # MSGFMT used to process po files
380 # 4. Variables that will be used to replace variables in some_file.in
381 # src/support/package.C.in:
382 # TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
383 # lib/lyx2lyx/lyx2lyx_version.py.in
386 # PACKAGE_VERSION, VERSION_INFO
388 # full path name is used to build msvs project files
389 # and to replace TOP_SRCDIR in package.C
390 env['TOP_SRCDIR'] = Dir(top_src_dir).abspath
391 # needed by src/version.C.in => src/version.C
392 env['PACKAGE_VERSION'] = package_version
394 # determine share_dir etc
395 packaging_method = env.get('packaging')
396 if packaging_method == 'windows':
397 share_dir = 'Resources'
398 man_dir = 'Resources/man/man1'
399 locale_dir = 'Resources/locale'
400 default_prefix = 'c:/program files/lyx'
402 share_dir = 'share/lyx'
404 locale_dir = 'share/locale'
405 default_prefix = '/usr/local/'
407 # install to default_prefix by default
408 # program suffix: can be yes, or a string
409 if env.has_key('version_suffix'):
410 if env['version_suffix'] in true_strings:
411 program_suffix = package_version
412 elif env['version_suffix'] in false_strings:
415 program_suffix = env['version_suffix']
418 # used by package.C.in
419 env['PROGRAM_SUFFIX'] = program_suffix
421 # whether or not add suffix to file and directory names
422 add_suffix = packaging_method != 'windows'
423 # LYX_DIR are different (used in package.C.in)
425 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir + program_suffix)).abspath
427 env['LYX_DIR'] = Dir(os.path.join(prefix, share_dir)).abspath
428 # we need absolute path for package.C
429 env['LOCALEDIR'] = Dir(os.path.join(prefix, locale_dir)).abspath
432 #---------------------------------------------------------
433 # Setting building environment (Tools, compiler flags etc)
434 #---------------------------------------------------------
436 # Since Tool('mingw') will reset CCFLAGS etc, this should be
437 # done before getEnvVariable
438 if platform_name == 'win32':
444 env.AppendUnique(CPPPATH = ['#c:/MinGW/include'])
446 # we differentiate between hard-coded options and default options
447 # hard-coded options are required and will always be there
448 # default options can be replaced by enviromental variables or command line options
449 CCFLAGS_required = []
450 LINKFLAGS_required = []
453 # under windows, scons is confused by .C/.c and uses gcc instead of
454 # g++. I am forcing the use of g++ here. This is expected to change
455 # after lyx renames all .C files to .cpp
457 # save the old c compiler and CCFLAGS (used by libintl)
458 C_COMPILER = env.subst('$CC')
459 C_CCFLAGS = env.subst('$CCFLAGS').split()
460 # if we use ms vc, the commands are fine (cl.exe and link.exe)
462 # /TP treat all source code as C++
463 # C4819: The file contains a character that cannot be represented
464 # in the current code page (number)
465 # C4996: foo was decleared deprecated
466 CCFLAGS_required.extend(['/TP', '/EHsc'])
467 CCFLAGS_default.extend(['/wd4819', '/wd4996', '/nologo', '/MD'])
469 if env.has_key('CXX') and env['CXX']:
470 env['CC'] = env.subst('$CXX')
471 env['LINK'] = env.subst('$CXX')
476 # for debug/release mode
477 if env.has_key('optimization') and env['optimization'] is not None:
478 # if user supplies optimization flags, use it anyway
479 CCFLAGS_required.extend(env['optimization'].split())
480 # and do not use default
481 set_default_optimization_flags = False
483 set_default_optimization_flags = True
487 CCFLAGS_required.append('/Zi')
488 LINKFLAGS_required.extend(['/debug', '/map'])
490 CCFLAGS_required.append('-g')
491 CCFLAGS_default.append('-O')
492 elif mode == 'release' and set_default_optimization_flags:
494 CCFLAGS_default.append('/O2')
496 CCFLAGS_default.append('-O2')
498 # msvc uses separate tools for profiling
499 if env.has_key('profiling') and env['profiling']:
501 print 'Visual C++ does not use profiling options'
503 CCFLAGS_required.append('-pg')
504 LINKFLAGS_required.append('-pg')
506 if env.has_key('warnings') and env['warnings']:
508 CCFLAGS_default.append('/W2')
510 # Note: autotools detect gxx version and pass -W for 3.x
511 # and -Wextra for other versions of gcc
512 CCFLAGS_default.append('-Wall')
514 # Now, set the variables as follows:
515 # 1. if command line option exists: replace default
516 # 2. then if s envronment variable exists: replace default
517 # 3. set variable to required + default
518 def setEnvVariable(env, name, required = None, default = None, split = True):
519 ''' env: environment to set variable
521 required: hardcoded options
522 default: default options that can be replaced by command line or
523 environment variables
524 split: whether or not split obtained variable like '-02 -g'
526 # 1. ARGUMENTS is already set to env[name], override default.
527 if ARGUMENTS.has_key(name):
529 # then use environment default
530 elif os.environ.has_key(name):
531 print "Acquiring variable %s from system environment: %s" % (name, os.environ[name])
532 default = os.environ[name]
534 default = default.split()
535 # the real value should be env[name] + default + required
538 if env.has_key(name):
539 value = str(env[name]).split()
540 if required is not None:
542 if default is not None:
546 if env.has_key(name):
547 value = str(env[name])
548 if required is not None:
549 value += " " + required
550 if default is not None:
551 value += " " + default
553 # print name, env[name]
555 setEnvVariable(env, 'DESTDIR', split=False)
556 setEnvVariable(env, 'CC')
557 setEnvVariable(env, 'LINK')
558 setEnvVariable(env, 'CPP')
559 setEnvVariable(env, 'CXX')
560 setEnvVariable(env, 'CXXCPP')
561 setEnvVariable(env, 'CCFLAGS', CCFLAGS_required, CCFLAGS_default)
562 setEnvVariable(env, 'CXXFLAGS')
563 setEnvVariable(env, 'CPPFLAGS')
564 setEnvVariable(env, 'LINKFLAGS', LINKFLAGS_required)
566 # if DESTDIR is not set...
567 if env.has_key('dest_dir'):
568 print "This option is obsolete. Please use DESTDIR instead."
569 env['DESTDIR'] = env['dest_dir']
572 #---------------------------------------------------------
573 # Frontend related variables (QTDIR etc)
574 #---------------------------------------------------------
576 if env.has_key('qt_dir') and env['qt_dir']:
577 env['QTDIR'] = env['qt_dir']
578 elif os.path.isdir(os.environ.get('QTDIR', '/usr/lib/qt-3.3')):
579 env['QTDIR'] = os.environ.get('QTDIR', '/usr/lib/qt-3.3')
581 # if there is a valid QTDIR, set path for lib and bin directories
582 if env.has_key('QTDIR'):
583 # add path to the qt tools
584 if os.path.isdir(os.path.join(env['QTDIR'], 'lib')):
585 env.AppendUnique(LIBPATH = [os.path.join(env['QTDIR'], 'lib')])
586 # set environment so that moc etc can be found even if its path is not set properly
587 if os.path.isdir(os.path.join(env['QTDIR'], 'bin')):
588 os.environ['PATH'] += os.pathsep + os.path.join(env['QTDIR'], 'bin')
589 env.PrependENVPath('PATH', os.path.join(env['QTDIR'], 'bin'))
591 if env.has_key('qt_lib_path') and env['qt_lib_path']:
592 qt_lib_path = env.subst('$qt_lib_path')
593 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'lib')):
594 qt_lib_path = env.subst('$QTDIR/lib')
595 # this is the path for cygwin.
596 elif os.path.isdir(os.path.join('/usr/lib/', frontend, 'lib')):
597 qt_lib_path = '/usr/lib/%s/lib' % frontend
599 print "Qt library directory is not found. Please specify it using qt_lib_path"
601 env.AppendUnique(LIBPATH = [qt_lib_path])
602 # qt4 seems to be using pkg_config
603 env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
605 if env.has_key('qt_inc_path') and env['qt_inc_path']:
606 qt_inc_path = env['qt_inc_path']
607 elif env.has_key('QTDIR') and os.path.isdir(os.path.join(env.subst('$QTDIR'), 'include')):
608 qt_inc_path = '$QTDIR/include'
609 # this is the path for cygwin.
610 elif os.path.isdir('/usr/include/' + frontend):
611 qt_inc_path = '/usr/include/' + frontend
613 print "Qt include directory not found. Please specify it using qt_inc_path"
615 # Note that this CPPPATH is for testing only
616 # it will be removed before calling SConscript
617 env['CPPPATH'] = [qt_inc_path]
620 # extra_inc_path and extra_lib_path
623 if env.has_key('extra_inc_path') and env['extra_inc_path']:
624 extra_inc_paths.append(env['extra_inc_path'])
625 if env.has_key('extra_lib_path') and env['extra_lib_path']:
626 env.AppendUnique(LIBPATH = [env['extra_lib_path']])
627 if env.has_key('extra_inc_path1') and env['extra_inc_path1']:
628 extra_inc_paths.append(env['extra_inc_path1'])
629 if env.has_key('extra_lib_path1') and env['extra_lib_path1']:
630 env.AppendUnique(LIBPATH = [env['extra_lib_path1']])
631 if env.has_key('extra_bin_path') and env['extra_bin_path']:
632 # only the first one is needed (a scons bug?)
633 os.environ['PATH'] += os.pathsep + env['extra_bin_path']
634 env.PrependENVPath('PATH', env['extra_bin_path'])
635 # extra_inc_paths will be used later by intlenv etc
636 env.AppendUnique(CPPPATH = extra_inc_paths)
639 #----------------------------------------------------------
641 #----------------------------------------------------------
643 conf = Configure(env,
645 'CheckPkgConfig' : utils.checkPkgConfig,
646 'CheckPackage' : utils.checkPackage,
647 'CheckMkdirOneArg' : utils.checkMkdirOneArg,
648 'CheckSelectArgType' : utils.checkSelectArgType,
649 'CheckBoostLibraries' : utils.checkBoostLibraries,
650 'CheckCommand' : utils.checkCommand,
651 'CheckCXXGlobalCstd' : utils.checkCXXGlobalCstd,
652 'CheckLC_MESSAGES' : utils.checkLC_MESSAGES,
653 'CheckIconvConst' : utils.checkIconvConst,
657 # pkg-config? (if not, we use hard-coded options)
659 if conf.CheckPkgConfig('0.15.0'):
660 env['HAS_PKG_CONFIG'] = True
662 print 'pkg-config >= 0.1.50 is not found'
663 env['HAS_PKG_CONFIG'] = False
664 env_cache['HAS_PKG_CONFIG'] = env['HAS_PKG_CONFIG']
666 env['HAS_PKG_CONFIG'] = env_cache['HAS_PKG_CONFIG']
668 # zlib? This is required. (fast_start assumes the existance of zlib)
670 if (not use_vc and not conf.CheckLibWithHeader('z', 'zlib.h', 'C')) \
671 or (use_vc and not conf.CheckLibWithHeader('zdll', 'zlib.h', 'C')):
672 print 'Did not find zdll.lib or zlib.h, exiting!'
674 has_iconv = conf.CheckLib('iconv')
675 has_libiconv = conf.CheckLib('libiconv')
677 env['ICONV_LIB'] = 'iconv'
679 env['ICONV_LIB'] = 'libiconv'
681 print 'Did not find iconv or libiconv, exiting!'
683 env_cache['ICONV_LIB'] = env['ICONV_LIB']
685 env['ICONV_LIB'] = env_cache['ICONV_LIB']
690 # qt3 does not use pkg_config
691 if frontend == 'qt3':
692 # windows lib name is qt-mt3
693 if not conf.CheckLibWithHeader('qt-mt', 'qapp.h', 'c++', 'QApplication qapp();') \
694 and not conf.CheckLibWithHeader('qt-mt3', 'qapp.h', 'c++', 'QApplication qapp();'):
695 print 'Did not find qt libraries, exiting!'
697 elif frontend == 'qt4':
699 # first: try pkg_config
700 if env['HAS_PKG_CONFIG']:
701 succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
702 # FIXME: use pkg_config information?
703 #env['QT4_PKG_CONFIG'] = succ
704 # second: try to link to it
706 # Under linux, I can test the following perfectly
707 # Under windows, lib names need to passed as libXXX4.a ...
708 succ = conf.CheckLibWithHeader('QtCore', 'QtGui/QApplication', 'c++', 'QApplication qapp();') or \
709 conf.CheckLibWithHeader('QtCore4', 'QtGui/QApplication', 'c++', 'QApplication qapp();')
710 # third: try to look up the path
713 for lib in ['QtCore', 'QtGui']:
714 # windows version has something like QtGui4 ...
715 if not (os.path.isfile(os.path.join(qt_lib_path, 'lib%s.a' % lib)) or \
716 os.path.isfile(os.path.join(qt_lib_path, 'lib%s4.a' % lib))):
719 # still can not find it
721 print "Qt4 libraries are found."
723 print 'Did not find qt libraries, exiting!'
726 # now, if msvc2005 is used, we will need that QT_LIB_PATH/QT_LIB.manifest file
728 if frontend == 'qt3':
729 manifest = os.path.join(qt_lib_path, 'qt-mt3.dll.manifest')
730 elif frontend == 'qt4':
732 manifest = os.path.join(qt_lib_path, 'QtGuid4.dll.manifest')
734 manifest = os.path.join(qt_lib_path, 'QtGui4.dll.manifest')
735 if os.path.isfile(manifest):
736 env['LINKCOM'] = [env['LINKCOM'], 'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % manifest]
741 if conf.CheckLib('socket'):
742 socket_libs.append('socket')
743 # nsl is the network services library and provides a
744 # transport-level interface to networking services.
745 if conf.CheckLib('nsl'):
746 socket_libs.append('nsl')
747 env_cache['SOCKET_LIBS'] = socket_libs
749 socket_libs = env_cache['SOCKET_LIBS']
751 # check available boost libs (since lyx1.4 does not use iostream)
753 for lib in ['signals', 'regex', 'filesystem', 'iostreams']:
754 if os.path.isdir(os.path.join(top_src_dir, 'boost', 'libs', lib)):
755 boost_libs.append(lib)
758 # check boost libraries
759 boost_opt = ARGUMENTS.get('boost', 'auto')
760 # check for system boost
761 lib_paths = env['LIBPATH'] + ['/usr/lib', '/usr/local/lib']
762 inc_paths = env['CPPPATH'] + ['/usr/include', '/usr/local/include']
763 # default to $BUILDDIR/libs (use None since this path will be added anyway)
765 # here I assume that all libraries are in the same directory
766 if boost_opt == 'included':
767 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
768 included_boost = True
769 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
770 elif boost_opt == 'auto':
771 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
772 # if not found, use local boost
774 boost_libraries = ['included_boost_%s' % x for x in boost_libs]
775 included_boost = True
776 env['BOOST_INC_PATH'] = '$TOP_SRCDIR/boost'
778 included_boost = False
779 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
780 elif boost_opt == 'system':
781 res = conf.CheckBoostLibraries(boost_libs, lib_paths, inc_paths, boost_version, mode == 'debug')
783 print "Can not find system boost libraries with version %s " % boost_version
784 print "Please supply a path through extra_lib_path and try again."
785 print "Or use boost=included to use included boost libraries."
788 included_boost = False
789 (boost_libraries, boost_libpath, env['BOOST_INC_PATH']) = res
790 env_cache['BOOST_LIBRARIES'] = boost_libraries
791 env_cache['INCLUDED_BOOST'] = included_boost
792 env_cache['BOOST_INC_PATH'] = env['BOOST_INC_PATH']
793 env_cache['BOOST_LIBPATH'] = boost_libpath
795 boost_libraries = env_cache['BOOST_LIBRARIES']
796 included_boost = env_cache['INCLUDED_BOOST']
797 env['BOOST_INC_PATH'] = env_cache['BOOST_INC_PATH']
798 boost_libpath = env_cache['BOOST_LIBPATH']
800 if boost_libpath is not None:
801 env.AppendUnique(LIBPATH = [boost_libpath])
804 env['ENABLE_NLS'] = env['nls']
807 if not env['ENABLE_NLS']:
809 included_gettext = False
811 # check gettext libraries
812 gettext_opt = ARGUMENTS.get('gettext', 'auto')
813 # check for system gettext
815 if gettext_opt in ['auto', 'system']:
816 if conf.CheckLib('intl'):
817 included_gettext = False
821 if gettext_opt == 'system':
822 print "Can not find system gettext library"
823 print "Please supply a path through extra_lib_path and try again."
824 print "Or use gettext=included to use included gettext libraries."
826 # now, auto and succ = false, or gettext=included
828 # we do not need to set LIBPATH now.
829 included_gettext = True
830 intl_libs = ['included_intl']
831 env_cache['INCLUDED_GETTEXT'] = included_gettext
832 env_cache['INTL_LIBS'] = intl_libs
834 included_gettext = env_cache['INCLUDED_GETTEXT']
835 intl_libs = env_cache['INTL_LIBS']
838 # check for msgfmt command
840 env['MSGFMT'] = conf.CheckCommand('msgfmt')
841 env_cache['MSGFMT'] = env['MSGFMT']
843 env['MSGFMT'] = env_cache['MSGFMT']
845 # check uic and moc commands for qt frontends
847 if frontend[:2] == 'qt' and (conf.CheckCommand('uic') == None \
848 or conf.CheckCommand('moc') == None):
849 print 'uic or moc command is not found for frontend', frontend
853 # Customized builders
855 # install customized builders
856 env['BUILDERS']['substFile'] = Builder(action = utils.env_subst)
859 #----------------------------------------------------------
860 # Generating config.h
861 #----------------------------------------------------------
862 aspell_lib = 'aspell'
863 # assume that we use aspell, aspelld compiled for msvc
864 if platform_name == 'win32' and mode == 'debug' and use_vc:
865 aspell_lib = 'aspelld'
867 # check the existence of config.h
868 config_h = os.path.join(env.Dir('$BUILDDIR/common').path, 'config.h')
869 boost_config_h = os.path.join(env.Dir('$BUILDDIR/boost').path, 'config.h')
870 if not fast_start or not os.path.isfile(boost_config_h) \
871 or not os.path.isfile(config_h):
873 print "Creating %s..." % boost_config_h
875 utils.createConfigFile(conf,
876 config_file = boost_config_h,
877 config_pre = '''/* boost/config.h. Generated by SCons. */
882 * This file is part of LyX, the document processor.
883 * Licence details can be found in the file COPYING.
885 * This is the compilation configuration file for LyX.
886 * It was generated by scon.
887 * You might want to change some of the defaults if something goes wrong
888 * during the compilation.
891 #ifndef _BOOST_CONFIG_H
892 #define _BOOST_CONFIG_H
895 ('ostream', 'HAVE_OSTREAM', 'cxx'),
896 ('locale', 'HAVE_LOCALE', 'cxx'),
897 ('sstream', 'HAVE_SSTREAM', 'cxx'),
898 #('newapis.h', 'HAVE_NEWAPIS_H', 'c'),
901 (env.has_key('assertions') and env['assertions'],
903 'Define if you want assertions to be enabled in the code'
908 #if defined(HAVE_OSTREAM) && defined(HAVE_LOCALE) && defined(HAVE_SSTREAM)
909 # define USE_BOOST_FORMAT 1
911 # define USE_BOOST_FORMAT 0
914 #if !defined(ENABLE_ASSERTIONS)
915 # define BOOST_DISABLE_ASSERTS 1
917 #define BOOST_ENABLE_ASSERT_HANDLER 1
919 #define BOOST_DISABLE_THREADS 1
920 #define BOOST_NO_WSTRING 1
923 # define BOOST_POSIX 1
926 #define BOOST_ALL_NO_LIB 1
928 #if defined(HAVE_NEWAPIS_H)
929 # define WANT_GETFILEATTRIBUTESEX_WRAPPER 1
936 print "\nGenerating %s..." % config_h
938 # AIKSAURUS_H_LOCATION
939 if (conf.CheckCXXHeader("Aiksaurus.h")):
940 aik_location = '<Aiksaurus.h>'
941 elif (conf.CheckCXXHeader("Aiksaurus/Aiksaurus.h")):
942 aik_location = '<Aiksaurus/Aiksaurus.h>'
946 # determine headers to use
947 spell_opt = ARGUMENTS.get('spell', 'auto')
948 env['USE_ASPELL'] = False
949 env['USE_PSPELL'] = False
950 env['USE_ISPELL'] = False
951 if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
952 spell_engine = 'USE_ASPELL'
953 elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
954 spell_engine = 'USE_PSPELL'
955 elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
956 spell_engine = 'USE_ISPELL'
960 if spell_engine is not None:
961 env[spell_engine] = True
963 if spell_opt == 'auto':
964 print "Warning: Can not locate any spell checker"
965 elif spell_opt != 'no':
966 print "Warning: Can not locate specified spell checker:", spell_opt
969 # check arg types of select function
970 (select_arg1, select_arg234, select_arg5) = conf.CheckSelectArgType()
974 result = utils.createConfigFile(conf,
975 config_file = config_h,
976 config_pre = '''/* config.h. Generated by SCons. */
981 * This file is part of LyX, the document processor.
982 * Licence details can be found in the file COPYING.
984 * This is the compilation configuration file for LyX.
985 * It was generated by scon.
986 * You might want to change some of the defaults if something goes wrong
987 * during the compilation.
994 ('io.h', 'HAVE_IO_H', 'c'),
995 ('limits.h', 'HAVE_LIMITS_H', 'c'),
996 ('locale.h', 'HAVE_LOCALE_H', 'c'),
997 ('process.h', 'HAVE_PROCESS_H', 'c'),
998 ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
999 ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
1000 ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
1001 ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
1002 ('sys/utime.h', 'HAVE_SYS_UTIME_H', 'c'),
1003 ('sys/socket.h', 'HAVE_SYS_SOCKET_H', 'c'),
1004 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1005 ('utime.h', 'HAVE_UTIME_H', 'c'),
1006 ('direct.h', 'HAVE_DIRECT_H', 'c'),
1007 ('istream', 'HAVE_ISTREAM', 'cxx'),
1008 ('ios', 'HAVE_IOS', 'cxx'),
1011 ('open', 'HAVE_OPEN', None),
1012 ('close', 'HAVE_CLOSE', None),
1013 ('popen', 'HAVE_POPEN', None),
1014 ('pclose', 'HAVE_PCLOSE', None),
1015 ('_open', 'HAVE__OPEN', None),
1016 ('_close', 'HAVE__CLOSE', None),
1017 ('_popen', 'HAVE__POPEN', None),
1018 ('_pclose', 'HAVE__PCLOSE', None),
1019 ('getpid', 'HAVE_GETPID', None),
1020 ('_getpid', 'HAVE__GETPID', None),
1021 ('mkdir', 'HAVE_MKDIR', None),
1022 ('_mkdir', 'HAVE__MKDIR', None),
1023 ('mktemp', 'HAVE_MKTEMP', None),
1024 ('mkstemp', 'HAVE_MKSTEMP', None),
1025 ('strerror', 'HAVE_STRERROR', None),
1026 ('count', 'HAVE_STD_COUNT', '''
1027 #include <algorithm>
1031 return std::count(a, a+5, 'l');
1034 ('getcwd', 'HAVE_GETCWD', None),
1035 ('setenv', 'HAVE_SETENV', None),
1036 ('putenv', 'HAVE_PUTENV', None),
1037 ('fcntl', 'HAVE_FCNTL', None),
1040 ('std::istreambuf_iterator<std::istream>', 'HAVE_DECL_ISTREAMBUF_ITERATOR',
1041 '#include <streambuf>\n#include <istream>')
1044 ('gdi32', 'HAVE_LIBGDI32'),
1045 (('Aiksaurus', 'libAiksaurus'), 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB'),
1048 (conf.CheckType('pid_t', includes='#include <sys/types.h>'),
1050 'Define is sys/types.h does not have pid_t',
1052 '#define pid_t int',
1054 (conf.CheckCXXGlobalCstd(),
1056 'Define if your C++ compiler puts C library functions in the global namespace'
1058 (conf.CheckMkdirOneArg(),
1059 'MKDIR_TAKES_ONE_ARG',
1060 'Define if mkdir takes only one argument.'
1062 (conf.CheckIconvConst(),
1064 'Define as const if the declaration of iconv() needs const.',
1065 '#define ICONV_CONST const',
1066 '#define ICONV_CONST',
1068 (conf.CheckLC_MESSAGES(),
1070 'Define if your <locale.h> file defines LC_MESSAGES.'
1072 (devel_version, 'DEVEL_VERSION', 'Whether or not a development version'),
1075 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1077 (env['nls'] and not included_gettext,
1079 'Define to 1 if using system gettext library'
1081 (env.has_key('warnings') and env['warnings'],
1083 'Define this if you want to see the warning directives put here and there by the developpers to get attention'
1085 (env.has_key('concept_checks') and env['concept_checks'],
1086 '_GLIBCXX_CONCEPT_CHECKS',
1087 'libstdc++ concept checking'
1089 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1091 'libstdc++ debug mode'
1093 (env.has_key('stdlib_debug') and env['stdlib_debug'],
1094 '_GLIBCXX_DEBUG_PEDANTIC',
1095 'libstdc++ pedantic debug mode'
1097 (os.name != 'nt', 'BOOST_POSIX',
1098 'Indicates to boost which API to use (posix or windows).'
1100 (spell_engine is not None, spell_engine,
1101 'Spell engine to use'
1103 # we need to know the byte order for unicode conversions
1104 (sys.byteorder == 'big', 'WORDS_BIGENDIAN',
1105 'Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX).'
1109 ('#define PACKAGE "%s%s"' % (package, program_suffix),
1111 ('#define PACKAGE_BUGREPORT "%s"' % package_bugreport,
1112 'Define to the address where bug reports for this package should be sent.'),
1113 ('#define PACKAGE_NAME "%s"' % package_name,
1114 'Define to the full name of this package.'),
1115 ('#define PACKAGE_STRING "%s"' % package_string,
1116 'Define to the full name and version of this package.'),
1117 ('#define PACKAGE_TARNAME "%s"' % package_tarname,
1118 'Define to the one symbol short name of this package.'),
1119 ('#define PACKAGE_VERSION "%s"' % package_version,
1120 'Define to the version of this package.'),
1121 ('#define BOOST_ALL_NO_LIB 1',
1122 'disable automatic linking of boost libraries.'),
1123 ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
1124 'Packaging method'),
1125 ('#define AIKSAURUS_H_LOCATION ' + aik_location,
1126 'Aiksaurus include file'),
1127 ('#define SELECT_TYPE_ARG1 %s' % select_arg1,
1128 "Define to the type of arg 1 for `select'."),
1129 ('#define SELECT_TYPE_ARG234 %s' % select_arg234,
1130 "Define to the type of arg 2, 3, 4 for `select'."),
1131 ('#define SELECT_TYPE_ARG5 %s' % select_arg5,
1132 "Define to the type of arg 5 for `select'."),
1134 config_post = '''/************************************************************
1135 ** You should not need to change anything beyond this point */
1137 #ifndef HAVE_STRERROR
1138 #if defined(__cplusplus)
1141 char * strerror(int n);
1145 #ifndef HAVE_DECL_MKSTEMP
1146 #if defined(__cplusplus)
1153 #include <../boost/config.h>
1159 # these keys are needed in env
1160 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1161 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1162 # USE_ASPELL etc does not go through result
1163 if result.has_key(key):
1164 env[key] = result[key]
1165 env_cache[key] = env[key]
1168 # if nls=yes and gettext=included, create intl/config.h
1169 # intl/libintl.h etc
1171 intl_config_h = os.path.join(env.Dir('$BUILDDIR/intl').path, 'config.h')
1172 if env['nls'] and included_gettext:
1174 print "Creating %s..." % intl_config_h
1176 # create intl/config.h
1177 result = utils.createConfigFile(conf,
1178 config_file = intl_config_h,
1179 config_pre = '''/* intl/config.h. Generated by SCons. */
1184 * This file is part of LyX, the document processor.
1185 * Licence details can be found in the file COPYING.
1187 * This is the compilation configuration file for LyX.
1188 * It was generated by scon.
1189 * You might want to change some of the defaults if something goes wrong
1190 * during the compilation.
1197 ('unistd.h', 'HAVE_UNISTD_H', 'c'),
1198 ('inttypes.h', 'HAVE_INTTYPES_H', 'c'),
1199 ('string.h', 'HAVE_STRING_H', 'c'),
1200 ('strings.h', 'HAVE_STRINGS_H', 'c'),
1201 ('argz.h', 'HAVE_ARGZ_H', 'c'),
1202 ('limits.h', 'HAVE_LIMITS_H', 'c'),
1203 ('alloca.h', 'HAVE_ALLOCA_H', 'c'),
1204 ('stddef.h', 'HAVE_STDDEF_H', 'c'),
1205 ('stdint.h', 'HAVE_STDINT_H', 'c'),
1206 ('sys/param.h', 'HAVE_SYS_PARAM_H', 'c'),
1209 ('getcwd', 'HAVE_GETCWD', None),
1210 ('stpcpy', 'HAVE_STPCPY', None),
1211 ('strcasecmp', 'HAVE_STRCASECMP', None),
1212 ('strdup', 'HAVE_STRDUP', None),
1213 ('strtoul', 'HAVE_STRTOUL', None),
1214 ('alloca', 'HAVE_ALLOCA', None),
1215 ('__fsetlocking', 'HAVE___FSETLOCKING', None),
1216 ('mempcpy', 'HAVE_MEMPCPY', None),
1217 ('__argz_count', 'HAVE___ARGZ_COUNT', None),
1218 ('__argz_next', 'HAVE___ARGZ_NEXT', None),
1219 ('__argz_stringify', 'HAVE___ARGZ_STRINGIFY', None),
1220 ('setlocale', 'HAVE_SETLOCALE', None),
1221 ('tsearch', 'HAVE_TSEARCH', None),
1222 ('getegid', 'HAVE_GETEGID', None),
1223 ('getgid', 'HAVE_GETGID', None),
1224 ('getuid', 'HAVE_GETUID', None),
1225 ('wcslen', 'HAVE_WCSLEN', None),
1226 ('asprintf', 'HAVE_ASPRINTF', None),
1227 ('wprintf', 'HAVE_WPRINTF', None),
1228 ('snprintf', 'HAVE_SNPRINTF', None),
1229 ('printf', 'HAVE_POSIX_PRINTF', None),
1230 ('fcntl', 'HAVE_FCNTL', None),
1233 ('intmax_t', 'HAVE_INTMAX_T', None),
1234 ('long double', 'HAVE_LONG_DOUBLE', None),
1235 ('long long', 'HAVE_LONG_LONG', None),
1236 ('wchar_t', 'HAVE_WCHAR_T', None),
1237 ('wint_t', 'HAVE_WINT_T', None),
1238 ('uintmax_t', 'HAVE_INTTYPES_H_WITH_UINTMAX', '#include <inttypes.h>'),
1239 ('uintmax_t', 'HAVE_STDINT_H_WITH_UINTMAX', '#include <stdint.h>'),
1245 (conf.CheckLC_MESSAGES(),
1247 'Define if your <locale.h> file defines LC_MESSAGES.'
1249 (conf.CheckIconvConst(),
1251 'Define as const if the declaration of iconv() needs const.',
1252 '#define ICONV_CONST const',
1253 '#define ICONV_CONST',
1255 (conf.CheckType('intmax_t', includes='#include <stdint.h>') or \
1256 conf.CheckType('intmax_t', includes='#include <inttypes.h>'),
1258 "Define to 1 if you have the `intmax_t' type."
1260 (env.has_key('nls') and env['nls'],
1262 "Define to 1 if translation of program messages to the user's native anguage is requested.",
1266 ('#define HAVE_ICONV 1', 'Define if iconv or libiconv is found')
1268 config_post = '#endif'
1271 # these keys are needed in env
1272 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1273 'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1274 # USE_ASPELL etc does not go through result
1275 if result.has_key(key):
1276 env[key] = result[key]
1277 env_cache[key] = env[key]
1281 # this comes as a big surprise, without this line
1282 # (doing nothing obvious), adding fast_start=yes
1283 # to a build with fast_start=no will result in a rebuild
1284 # Note that the exact header file to check does not matter
1285 conf.CheckCHeader('io.h')
1286 # only a few variables need to be rescanned
1287 for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\
1288 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
1289 env[key] = env_cache[key]
1292 if env['nls'] and included_gettext:
1293 # only a few variables need to be rescanned
1294 for key in ['HAVE_ASPRINTF', 'HAVE_WPRINTF', 'HAVE_SNPRINTF', \
1295 'HAVE_POSIX_PRINTF', 'HAVE_LIBC']:
1296 env[key] = env_cache[key]
1298 # this looks misplaced, but intl/libintl.h is needed by src/message.C
1299 if env['nls'] and included_gettext:
1300 # libgnuintl.h.in => libintl.h
1301 env.substFile('$BUILDDIR/intl/libintl.h', '$TOP_SRCDIR/intl/libgnuintl.h.in')
1302 env.Command('$BUILDDIR/intl/libgnuintl.h', '$BUILDDIR/intl/libintl.h',
1303 [Copy('$TARGET', '$SOURCE')])
1306 # Finish auto-configuration
1309 #----------------------------------------------------------
1310 # Now set up our build process accordingly
1311 #----------------------------------------------------------
1316 # NOTE: Tool('qt') or Tool('qt4') will be loaded later
1317 # in their respective directory and specialized env.
1318 if frontend == 'qt3':
1319 # note: env.Tool('qt') my set QT_LIB to qt
1320 if platform_name == 'win32':
1321 qt_libs = ['qt-mt3']
1324 frontend_libs = qt_libs
1325 elif frontend == 'qt4':
1326 qt_libs = ['QtCore', 'QtGui']
1327 # set the right lib names
1328 if platform_name == 'win32':
1329 if mode == 'debug' and use_vc:
1330 qt_lib_suffix = 'd4'
1335 qt_lib_suffix = '_debug'
1338 frontend_libs = [x + qt_lib_suffix for x in qt_libs]
1341 if platform_name in ['win32', 'cygwin']:
1342 # the final link step needs stdc++ to succeed under mingw
1343 # FIXME: shouldn't g++ automatically link to stdc++?
1345 system_libs = [env['ICONV_LIB'], 'ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
1347 system_libs = [env['ICONV_LIB'], 'shlwapi', 'stdc++', 'z']
1348 elif platform_name == 'cygwin' and env['X11']:
1349 system_libs = [env['ICONV_LIB'], 'GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr',
1350 'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE',
1351 'resolv', 'pthread', 'z']
1353 system_libs = [env['ICONV_LIB'], 'z']
1356 ('HAVE_LIBGDI32', 'gdi32'),
1357 ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
1358 ('USE_ASPELL', aspell_lib),
1359 ('USE_ISPELL', 'ispell'),
1360 ('USE_PSPELL', 'pspell'),
1365 system_libs.append(lib[1])
1368 # Build parameters CPPPATH etc
1371 env.AppendUnique(LIBPATH = ['/usr/X11R6/lib'])
1374 # boost: for boost header files
1375 # BUILDDIR/common: for config.h
1376 # TOP_SRCDIR/src: for support/* etc
1378 env['CPPPATH'] += ['$BUILDDIR/common', '$TOP_SRCDIR/src']
1380 # Separating boost directories from CPPPATH stops scons from building
1381 # the dependency tree for boost header files, and effectively reduce
1382 # the null build time of lyx from 29s to 16s. Since lyx may tweak local
1383 # boost headers, this is only done for system boost headers.
1385 env.AppendUnique(CPPPATH = ['$BOOST_INC_PATH'])
1388 env.PrependUnique(CCFLAGS = ['/I$BOOST_INC_PATH'])
1390 env.PrependUnique(CCFLAGS = ['-I$BOOST_INC_PATH'])
1392 # for intl/config.h, intl/libintl.h and intl/libgnuintl.h
1393 if env['nls'] and included_gettext:
1394 env['CPPPATH'].append('$BUILDDIR/intl')
1396 # QT_INC_PATH is not needed for *every* source file
1397 env['CPPPATH'].remove(qt_inc_path)
1400 # A Link script for cygwin see
1401 # http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html
1402 # http://www.cygwin.com/ml/cygwin-apps/2004-09/msg00309.html
1405 if platform_name == 'cygwin':
1406 ld_script_path = '/usr/lib/qt3/mkspecs/cygwin-g++'
1407 ld_script = utils.installCygwinLDScript(ld_script_path)
1408 env.AppendUnique(LINKFLAGS = ['-Wl,--enable-runtime-pseudo-reloc',
1409 '-Wl,--script,%s' % ld_script, '-Wl,-s'])
1414 # fill in the version info
1415 env['VERSION_INFO'] = '''Configuration
1417 Special build flags: %s
1419 C Compiler flags: %s %s
1421 C++ Compiler LyX flags: %s
1422 C++ Compiler flags: %s %s
1424 Linker user flags: %s
1426 Builing directory: %s
1427 Local library directory: %s
1430 Frontend libraries: %s
1431 System libraries: %s
1432 include search path: %s
1438 ''' % (platform_name,
1439 env.subst('$CCFLAGS'), env.subst('$CC'),
1440 env.subst('$CPPFLAGS'), env.subst('$CFLAGS'),
1441 env.subst('$CXX'), env.subst('$CXXFLAGS'),
1442 env.subst('$CPPFLAGS'), env.subst('$CXXFLAGS'),
1443 env.subst('$LINKFLAGS'), env.subst('$LINKFLAGS'),
1444 env.subst('$BUILDDIR'), env.subst('$LOCALLIBPATH'),
1445 str(env['LIBPATH']), str(boost_libraries),
1446 str(frontend_libs), str(system_libs), str(env['CPPPATH']),
1447 frontend, packaging_method,
1448 prefix, env['LYX_DIR'])
1450 if frontend in ['qt3', 'qt4']:
1451 env['VERSION_INFO'] += ''' include dir: %s
1454 ''' % (qt_inc_path, qt_lib_path, env['X11'])
1457 print env['VERSION_INFO']
1460 # Mingw command line may be too short for our link usage,
1461 # Here we use a trick from scons wiki
1462 # http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/LongCmdLinesOnWin32
1464 # I also would like to add logging (commands only) capacity to the
1466 logfile = env.get('logfile', default_log_file)
1467 if logfile != '' or platform_name == 'win32':
1469 utils.setLoggedSpawn(env, logfile, longarg = (platform_name == 'win32'),
1470 info = '''# This is a log of commands used by scons to build lyx
1474 ''' % (time.asctime(), ' '.join(sys.argv),
1475 env['VERSION_INFO'].replace('\n','\n# ')) )
1480 # -h will print out help info
1481 Help(opts.GenerateHelpText(env))
1483 # save environment settings (for fast_start option)
1484 cache_file = open(env_cache_file, 'w')
1485 cPickle.dump(env_cache, cache_file)
1489 #----------------------------------------------------------
1491 #----------------------------------------------------------
1492 # this has been the source of problems on some platforms...
1493 # I find that I need to supply it with full path name
1494 env.SConsignFile(os.path.join(Dir(env['BUILDDIR']).abspath, '.sconsign'))
1495 # this usage needs further investigation.
1496 #env.CacheDir('%s/Cache/%s' % (env['BUILDDIR'], frontend))
1498 print "Building all targets recursively"
1500 if env.has_key('rebuild'):
1501 rebuild_targets = env['rebuild'].split(',')
1502 if 'none' in rebuild_targets or 'no' in rebuild_targets:
1503 rebuild_targets = []
1504 elif 'all' in rebuild_targets or 'yes' in rebuild_targets:
1505 # None: let scons decide which components to build
1506 # Forcing all components to be rebuilt is in theory not necessary
1507 rebuild_targets = None
1509 rebuild_targets = None
1511 def libExists(libname):
1512 ''' Check whether or not lib $LOCALLIBNAME/libname already exists'''
1513 return os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath)
1515 def appExists(apppath, appname):
1516 ''' Check whether or not application already exists'''
1517 return os.path.isfile(File(env.subst('$BUILDDIR/common/%s/${PROGPREFIX}%s$PROGSUFFIX' % (apppath, appname))).abspath)
1519 targets = BUILD_TARGETS
1520 # msvc need to pass full target name, so I have to look for path/lyx etc
1521 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
1522 or 'install' in targets or 'all' in targets
1523 build_boost = (included_boost and not libExists('boost_regex')) or 'boost' in targets
1524 build_intl = (included_gettext and not libExists('included_intl')) or 'intl' in targets
1525 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
1526 build_mathed = build_lyx or 'mathed' in targets
1527 build_insets = build_lyx or 'insets' in targets
1528 build_frontends = build_lyx or 'frontends' in targets
1529 build_graphics = build_lyx or 'graphics' in targets
1530 build_controllers = build_lyx or 'controllers' in targets
1531 build_client = True in ['client' in x for x in targets] \
1532 or 'install' in targets or 'all' in targets
1533 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
1534 or 'install' in targets or 'all' in targets
1535 build_lyxbase = build_lyx or 'lyxbase' in targets
1536 build_po = 'po' in targets or 'install' in targets or 'all' in targets
1537 build_qt3 = (build_lyx and frontend == 'qt3') or 'qt3' in targets
1538 build_qt4 = (build_lyx and frontend == 'qt4') or 'qt4' in targets
1539 build_msvs_projects = use_vc and 'msvs_projects' in targets
1542 # now, if rebuild_targets is specified, do not rebuild some targets
1543 if rebuild_targets is not None:
1545 def ifBuildLib(name, libname, old_value):
1546 # explicitly asked to rebuild
1547 if name in rebuild_targets:
1549 # else if not rebuild, and if the library already exists
1550 elif libExists(libname):
1552 # do not change the original value
1555 build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
1556 build_intl = ifBuildLib('intl', 'included_intl', build_intl)
1557 build_support = ifBuildLib('support', 'support', build_support)
1558 build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
1559 build_insets = ifBuildLib('insets', 'insets', build_insets)
1560 build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
1561 build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
1562 build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
1563 build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
1564 build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
1565 build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
1567 def ifBuildApp(name, appname, old_value):
1568 # explicitly asked to rebuild
1569 if name in rebuild_targets:
1571 # else if not rebuild, and if the library already exists
1572 elif appExists(name, appname):
1574 # do not change the original value
1577 build_tex2lyx = ifBuildApp('tex2lyx', 'tex2lyx', build_tex2lyx)
1578 build_client = ifBuildApp('client', 'lyxclient', build_client)
1580 # sync frontend and frontend (maybe build qt4 with frontend=qt3)
1592 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
1594 boostenv = env.Copy()
1596 # boost use its own config.h
1597 boostenv['CPPPATH'] = ['$TOP_SRCDIR/boost', '$BUILDDIR/boost'] + extra_inc_paths
1598 boostenv.AppendUnique(CCFLAGS = ['-DBOOST_USER_CONFIG="<config.h>"'])
1600 for lib in boost_libs:
1601 print 'Processing files in boost/libs/%s/src...' % lib
1602 boostlib = boostenv.StaticLibrary(
1603 target = '$LOCALLIBPATH/included_boost_%s' % lib,
1604 source = ['$BUILDDIR/boost/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1606 Alias('boost', boostlib)
1613 intlenv = env.Copy()
1615 print "Processing files in intl..."
1617 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
1619 # we need the original C compiler for these files
1620 intlenv['CC'] = C_COMPILER
1621 intlenv['CCFLAGS'] = C_CCFLAGS
1623 intlenv.Append(CCFLAGS=['/Dinline#', '/D__attribute__(x)#', '/Duintmax_t=UINT_MAX'])
1624 # intl does not use global config.h
1625 intlenv['CPPPATH'] = ['$BUILDDIR/intl'] + extra_inc_paths
1627 intlenv.Append(CCFLAGS = [
1628 r'-DLOCALEDIR=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1629 r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALEDIR'].replace('\\', '\\\\') + r'\"',
1630 r'-DLIBDIR=\"' + env['TOP_SRCDIR'].replace('\\', '\\\\') + r'/lib\"',
1632 '-DENABLE_RELOCATABLE=1',
1634 r'-DINSTALLDIR=\"' + prefix.replace('\\', '\\\\') + r'/lib\"',
1636 '-Dset_relocation_prefix=libintl_set_relocation_prefix',
1637 '-Drelocate=libintl_relocate',
1638 '-DDEPENDS_ON_LIBICONV=1',
1643 intl = intlenv.StaticLibrary(
1644 target = '$LOCALLIBPATH/included_intl',
1646 source = ['$BUILDDIR/intl/%s' % x for x in intl_files]
1652 # Now, src code under src/
1654 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1661 print "Processing files in src/support..."
1663 env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRCDIR/src/support/package.C.in')
1665 support = env.StaticLibrary(
1666 target = '$LOCALLIBPATH/support',
1667 source = ['$BUILDDIR/common/support/%s' % x for x in src_support_files]
1669 Alias('support', support)
1676 print "Processing files in src/mathed..."
1678 mathed = env.StaticLibrary(
1679 target = '$LOCALLIBPATH/mathed',
1680 source = ['$BUILDDIR/common/mathed/%s' % x for x in src_mathed_files]
1682 Alias('mathed', mathed)
1689 print "Processing files in src/insets..."
1691 insets = env.StaticLibrary(
1692 target = '$LOCALLIBPATH/insets',
1693 source = ['$BUILDDIR/common/insets/%s' % x for x in src_insets_files]
1695 Alias('insets', insets)
1702 print "Processing files in src/frontends..."
1704 frontends = env.StaticLibrary(
1705 target = '$LOCALLIBPATH/frontends',
1706 source = ['$BUILDDIR/common/frontends/%s' % x for x in src_frontends_files]
1708 Alias('frontends', frontends)
1715 print "Processing files in src/graphics..."
1717 graphics = env.StaticLibrary(
1718 target = '$LOCALLIBPATH/graphics',
1719 source = ['$BUILDDIR/common/graphics/%s' % x for x in src_graphics_files]
1721 Alias('graphics', graphics)
1724 if build_controllers:
1726 # src/frontends/controllers
1728 print "Processing files in src/frontends/controllers..."
1730 controllers = env.StaticLibrary(
1731 target = '$LOCALLIBPATH/controllers',
1732 source = ['$BUILDDIR/common/frontends/controllers/%s' % x for x in src_frontends_controllers_files]
1734 Alias('controllers', controllers)
1738 # src/frontend/qt3/4
1740 if build_qt3 or build_qt4:
1741 env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRCDIR/src/frontend/$frontend', duplicate = 0)
1744 print "Processing files in src/frontends/qt3..."
1747 # disable auto scan to speed up non build time
1748 qt3env['QT_AUTOSCAN'] = 0
1749 qt3env['QT_MOCHPREFIX'] = ''
1754 qt3env.AppendUnique(CPPPATH = [
1756 '$BUILDDIR/common/images',
1757 '$BUILDDIR/common/frontends',
1758 '$BUILDDIR/common/frontends/qt3',
1759 '$BUILDDIR/common/frontends/controllers',
1763 qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in src_frontends_qt3_moc_files]
1765 # manually moc and uic files for better performance
1766 qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
1768 qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
1769 src_frontends_qt3_ui_files]
1771 qt3_uiced_cc_files = []
1772 for x in qt3_uiced_files:
1773 qt3_uiced_cc_files.extend(x[1:])
1775 qt3 = qt3env.StaticLibrary(
1776 target = '$LOCALLIBPATH/qt3',
1777 source = ['$BUILDDIR/common/frontends/qt3/%s' % x for x in src_frontends_qt3_files] \
1778 + qt3_uiced_cc_files
1784 print "Processing files in src/frontends/qt4..."
1787 qt4env['QT_AUTOSCAN'] = 0
1789 # local qt4 toolset from
1790 # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
1792 # NOTE: I have to patch qt4.py since it does not automatically
1793 # process .C file!!! (add to cxx_suffixes )
1795 qt4env.Tool('qt4', [scons_dir])
1796 qt4env.EnableQt4Modules(qt_libs, debug = (mode == 'debug'))
1798 qt4env.AppendUnique(CPPPATH = [
1800 '$BUILDDIR/common/images',
1801 '$BUILDDIR/common/frontends',
1802 '$BUILDDIR/common/frontends/qt4',
1803 '$BUILDDIR/common/frontends/controllers',
1808 # FIXME: replace by something from pkg_config
1809 qt4env.Append(CCFLAGS = [
1811 '-DQT_CLEAN_NAMESPACE',
1819 qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in src_frontends_qt4_moc_files]
1824 resources = [qt4env.Uic4(x.split('.')[0]) for x in \
1825 ["$BUILDDIR/common/frontends/qt4/ui/%s" % x for x in src_frontends_qt4_ui_files]]
1828 # moc qt4_moc_files, the moced files are included in the original files
1830 qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
1832 qt4 = qt4env.StaticLibrary(
1833 target = '$LOCALLIBPATH/qt4',
1834 source = ['$BUILDDIR/common/frontends/qt4/%s' % x for x in src_frontends_qt4_files]
1843 env.BuildDir('$BUILDDIR/common', '$TOP_SRCDIR/src', duplicate = 0)
1845 print "Processing files in src/client..."
1847 if env['HAVE_FCNTL']:
1848 client = env.Program(
1849 target = '$BUILDDIR/common/client/lyxclient',
1850 LIBS = ['support'] + intl_libs + system_libs +
1851 socket_libs + boost_libraries,
1852 source = ['$BUILDDIR/common/client/%s' % x for x in src_client_files]
1854 Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
1855 client, [Copy('$TARGET', '$SOURCE')]))
1858 Alias('client', client)
1860 if env['HAVE_FCNTL']:
1861 # define client even if lyxclient is not built with rebuild=no
1862 client = [env.subst('$BUILDDIR/common/client/${PROGPREFIX}lyxclient$PROGSUFFIX')]
1871 print "Processing files in src/tex2lyx..."
1873 tex2lyx_env = env.Copy()
1875 tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
1876 tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
1878 for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C',
1879 'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
1880 env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
1881 [Copy('$TARGET', '$SOURCE')])
1883 tex2lyx = tex2lyx_env.Program(
1884 target = '$BUILDDIR/common/tex2lyx/tex2lyx',
1885 LIBS = ['support'] + boost_libraries + system_libs,
1886 source = ['$BUILDDIR/common/tex2lyx/%s' % x for x in src_tex2lyx_files]
1888 Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
1889 tex2lyx, [Copy('$TARGET', '$SOURCE')]))
1890 Alias('tex2lyx', tex2lyx)
1892 # define tex2lyx even if tex2lyx is not built with rebuild=no
1893 tex2lyx = [env.subst('$BUILDDIR/common/tex2lyx/${PROGPREFIX}tex2lyx$PROGSUFFIX')]
1900 print "Processing files in src..."
1902 env.substFile('$BUILDDIR/common/version.C', '$TOP_SRCDIR/src/version.C.in')
1904 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
1905 src_post_files.append('aspell.C')
1906 elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
1907 src_post_files.append('pspell.C')
1908 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
1909 src_post_files.append('ispell.C')
1911 # msvc requires at least one source file with main()
1912 # so I exclude main.C from lyxbase
1913 lyxbase_pre = env.StaticLibrary(
1914 target = '$LOCALLIBPATH/lyxbase_pre',
1915 source = ['$BUILDDIR/common/%s' % x for x in src_pre_files]
1917 lyxbase_post = env.StaticLibrary(
1918 target = '$LOCALLIBPATH/lyxbase_post',
1919 source = ["$BUILDDIR/common/%s" % x for x in src_post_files]
1921 Alias('lyxbase', lyxbase_pre)
1922 Alias('lyxbase', lyxbase_post)
1927 # Build lyx with given frontend
1930 target = '$BUILDDIR/$frontend/lyx',
1931 source = ['$BUILDDIR/common/main.C'],
1949 # [/path/to/lyx.ext] => lyx-qt3.ext
1950 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
1951 Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
1952 [Copy('$TARGET', '$SOURCE')]))
1955 # define lyx even if lyx is not built with rebuild=no
1956 lyx = [env.subst('$BUILDDIR/$frontend/${PROGPREFIX}lyx$PROGSUFFIX')]
1959 if build_msvs_projects:
1960 def build_project(target, full_target = None,
1961 src = [], inc = [], res = [], rebuildTargetOnly = True):
1962 ''' build mavs project files
1963 target: alias (correspond to directory name)
1964 full_target: full path/filename of the target
1968 rebuildTargetOnly: whether or not only rebuild this target
1970 For non-debug-able targets like static libraries, target (alias) is
1971 enough to build the target. For executable targets, msvs need to know
1972 the full path to start debug them.
1974 if rebuildTargetOnly:
1975 cmds = 'fast_start=yes rebuild='+target
1977 cmds = 'fast_start=yes'
1978 if full_target is None:
1979 build_target = target
1981 build_target = full_target
1983 proj = env.MSVSProject(
1984 target = target + env['MSVSPROJECTSUFFIX'],
1985 # this allows easy access to header files (along with source)
1986 srcs = [env.subst(x) for x in src + inc],
1987 incs = [env.subst('$TOP_SRCDIR/src/config.h')],
1988 localincs = [env.subst(x) for x in inc],
1989 resources = [env.subst(x) for x in res],
1990 buildtarget = build_target,
1994 Alias('msvs_projects', proj)
1997 for lib in boost_libs:
1998 boost_src += ['$TOP_SRCDIR/boost/libs/%s/src/%s' % (lib, x) for x in eval('boost_libs_%s_src_files' % lib)]
1999 build_project('boost', src = boost_src)
2001 build_project('intl', src = ['$TOP_SRCDIR/intl/%s' % x for x in intl_files],
2002 inc = ['$TOP_SRCDIR/intl/%s' % x for x in intl_header_files])
2004 build_project('support', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
2005 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2007 build_project('mathed', src = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files],
2008 inc = ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files])
2010 build_project('insets', src = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files],
2011 inc = ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files])
2013 build_project('frontends', src = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files],
2014 inc = ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files])
2016 build_project('graphics', src = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files],
2017 inc = ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files])
2019 build_project('controllers', src = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files],
2020 inc = ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files])
2022 build_project('qt3', src = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2023 inc = ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2024 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files])
2026 build_project('qt4', src = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2027 inc = ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2028 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files])
2030 build_project('client', src = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_files],
2031 inc = ['$TOP_SRCDIR/src/client/%s' % x for x in src_client_header_files],
2032 rebuildTargetOnly = False,
2033 full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
2035 build_project('tex2lyx', src = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files],
2036 inc = ['$TOP_SRCDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_header_files],
2037 rebuildTargetOnly = False,
2038 full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
2040 build_project('lyxbase', src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files],
2041 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files])
2043 if frontend == 'qt3':
2044 build_project('lyx',
2045 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2046 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2047 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2048 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2049 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2050 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2051 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2052 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_files + src_frontends_qt3_moc_files],
2053 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2054 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2055 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2056 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2057 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2058 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2059 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2060 ['$TOP_SRCDIR/src/frontends/qt3/%s' % x for x in src_frontends_qt3_header_files],
2061 res = ['$TOP_SRCDIR/src/frontends/qt3/ui/%s' % x for x in src_frontends_qt3_ui_files],
2062 rebuildTargetOnly = False,
2063 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2065 build_project('lyx',
2066 src = ['$TOP_SRCDIR/src/%s' % x for x in src_pre_files + src_post_files] + \
2067 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_files] + \
2068 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_files] + \
2069 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_files] + \
2070 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_files] + \
2071 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_files] + \
2072 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_files] + \
2073 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files + src_frontends_qt4_moc_files],
2074 inc = ['$TOP_SRCDIR/src/%s' % x for x in src_header_files] + \
2075 ['$TOP_SRCDIR/src/support/%s' % x for x in src_support_header_files] + \
2076 ['$TOP_SRCDIR/src/mathed/%s' % x for x in src_mathed_header_files] + \
2077 ['$TOP_SRCDIR/src/insets/%s' % x for x in src_insets_header_files] + \
2078 ['$TOP_SRCDIR/src/frontends/%s' % x for x in src_frontends_header_files] + \
2079 ['$TOP_SRCDIR/src/graphics/%s' % x for x in src_graphics_header_files] + \
2080 ['$TOP_SRCDIR/src/frontends/controllers/%s' % x for x in src_frontends_controllers_header_files] + \
2081 ['$TOP_SRCDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_header_files],
2082 res = ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files],
2083 rebuildTargetOnly = False,
2084 full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
2091 print 'Processing files in po...'
2096 # files to translate
2097 transfiles = glob.glob(os.path.join(env.subst('$TOP_SRCDIR'), 'po', '*.po'))
2098 # possibly *only* handle these languages
2100 if env.has_key('languages'):
2101 languages = env.make_list(env['lanauges'])
2102 # use defulat msgfmt
2104 if not env['MSGFMT']:
2105 print 'msgfmt does not exist. Can not process po files'
2108 env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
2110 for f in transfiles:
2112 fname = os.path.split(f)[1]
2114 country = fname.split('.')[0]
2116 if not languages or country in languages:
2117 gmo_files.extend(env.Transfiles(f))
2120 if 'install' in targets:
2122 # this part is a bit messy right now. Since scons will provide
2123 # --DESTDIR option soon, at least the dest_dir handling can be
2126 # how to join dest_dir and prefix
2127 def joinPaths(path1, path2):
2128 ''' join path1 and path2, do not use os.path.join because
2129 under window, c:\destdir\d:\program is invalid '''
2131 return os.path.normpath(path2)
2132 # separate drive letter
2133 (drive, path) = os.path.splitdrive(os.path.normpath(path2))
2134 # ignore drive letter, so c:\destdir + c:\program = c:\destdir\program
2135 return os.path.join(os.path.normpath(path1), path[1:])
2137 # install to dest_dir/prefix
2138 dest_dir = env.get('DESTDIR', None)
2139 dest_prefix_dir = joinPaths(dest_dir, env.Dir(prefix).abspath)
2140 # create the directory if needed
2141 if not os.path.isdir(dest_prefix_dir):
2143 os.makedirs(dest_prefix_dir)
2146 if not os.path.isdir(dest_prefix_dir):
2147 print 'Can not create directory', dest_prefix_dir
2150 if env.has_key('exec_prefix'):
2151 bin_dest_dir = joinPaths(dest_dir, Dir(env['exec_prefix']).abspath)
2153 bin_dest_dir = os.path.join(dest_prefix_dir, 'bin')
2155 share_dest_dir = os.path.join(dest_prefix_dir, share_dir + program_suffix)
2157 share_dest_dir = os.path.join(dest_prefix_dir, share_dir)
2158 man_dest_dir = os.path.join(dest_prefix_dir, man_dir)
2159 locale_dest_dir = os.path.join(dest_prefix_dir, locale_dir)
2163 # install executables (lyxclient may be None)
2166 version_suffix = program_suffix
2171 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
2172 target = os.path.join(bin_dest_dir, target_name)
2173 env.InstallAs(target, lyx)
2174 Alias('install', target)
2175 # install lyx as lyx-qt3
2176 target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
2177 target = os.path.join(bin_dest_dir, target_name)
2178 env.InstallAs(target, lyx)
2179 Alias('install', target)
2182 target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
2183 target = os.path.join(bin_dest_dir, target_name)
2184 env.InstallAs(target, tex2lyx)
2185 Alias('install', target)
2187 # install lyxclient, may not exist
2189 target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
2190 target = os.path.join(bin_dest_dir, target_name)
2191 env.InstallAs(target, client)
2192 Alias('install', target)
2196 for (dir,files) in [
2198 ('clipart', lib_clipart_files),
2199 ('examples', lib_examples_files),
2200 ('images', lib_images_files),
2201 ('images/math', lib_images_math_files),
2202 ('bind', lib_bind_files),
2203 ('kbd', lib_kbd_files),
2204 ('layouts', lib_layouts_files),
2205 ('scripts', lib_scripts_files),
2206 ('templates', lib_templates_files),
2207 ('tex', lib_tex_files),
2208 ('ui', lib_ui_files),
2209 ('doc', lib_doc_files),
2210 ('lyx2lyx', lib_lyx2lyx_files)]:
2211 dirs.append(env.Install(os.path.join(share_dest_dir, dir),
2212 [env.subst('$TOP_SRCDIR/lib/%s/%s' % (dir, file)) for file in files]))
2214 # lyx1.4.x does not have lyx2lyx_version.py.in
2215 if os.path.isfile(env.subst('$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')):
2216 # subst and install this file
2217 env.substFile(share_dest_dir + '/lyx2lyx/lyx2lyx_version.py',
2218 '$TOP_SRCDIR/lib/lyx2lyx/lyx2lyx_version.py.in')
2219 Alias('install', share_dest_dir + '/lyx2lyx/lyx2lyx_version.py')
2220 Alias('install', dirs)
2222 env.InstallAs(os.path.join(man_dest_dir, 'lyx' + version_suffix + '.1'),
2223 env.subst('$TOP_SRCDIR/lyx.man'))
2224 env.InstallAs(os.path.join(man_dest_dir, 'tex2lyx' + version_suffix + '.1'),
2225 env.subst('$TOP_SRCDIR/src/tex2lyx/tex2lyx.man'))
2226 env.InstallAs(os.path.join(man_dest_dir, 'lyxclient' + version_suffix + '.1'),
2227 env.subst('$TOP_SRCDIR/src/client/lyxclient.man'))
2228 Alias('install', [os.path.join(man_dest_dir, x + version_suffix + '.1') for
2229 x in ['lyx', 'tex2lyx', 'lyxclient']])
2231 # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
2232 for gmo in gmo_files:
2233 lan = os.path.split(str(gmo))[1].split('.')[0]
2234 dest_file = os.path.join(locale_dest_dir, lan, 'LC_MESSAGES', 'lyx' + program_suffix + '.mo')
2235 env.InstallAs(dest_file, gmo)
2236 Alias('install', dest_file)
2240 Alias('all', ['lyx', 'client', 'tex2lyx'])