]> git.lyx.org Git - lyx.git/blob - development/scons/SConscript
Scons: Better MSVS Projects support (now with debug)
[lyx.git] / development / scons / SConscript
1 # vi:filetype=python:expandtab:tabstop=2:shiftwidth=2
2
3 # file SConscript
4 #
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7 #
8 # \author Bo Peng
9 # Full author contact details are available in file CREDITS.
10
11 import os, sys
12 sys.path.append('config')
13 from scons_utils import globSource
14
15 Import('env')
16
17 targets = env['BUILD_TARGETS']
18 # msvc need to pass full target name, so I have to look for path/lyx etc
19 build_lyx = targets == [] or True in ['lyx' in x for x in targets] \
20   or 'install' in targets or 'all' in targets
21 build_boost = env['INCLUDED_BOOST'] or 'boost' in targets
22 build_intl = env['INCLUDED_GETTEXT'] or 'intl' in targets
23 build_support = build_lyx or True in [x in targets for x in ['support', 'client', 'tex2lyx']]
24 build_mathed = build_lyx or 'mathed' in targets
25 build_insets = build_lyx or 'insets' in targets
26 build_frontends = build_lyx or 'frontends' in targets
27 build_graphics = build_lyx or 'graphics' in targets
28 build_controllers = build_lyx or 'controllers' in targets
29 build_client = True in ['client' in x for x in targets] \
30   or 'install' in targets or 'all' in targets
31 build_tex2lyx = True in ['tex2lyx' in x for x in targets] \
32   or 'install' in targets or 'all' in targets
33 build_lyxbase = build_lyx or 'lyxbase' in targets
34 build_po = 'po' in targets or 'install' in targets or 'all' in targets
35 build_qt3 = (build_lyx and env['frontend'] == 'qt3') or 'qt3' in targets
36 build_qt4 = (build_lyx and env['frontend'] == 'qt4') or 'qt4' in targets
37 build_msvs_projects = env['USE_VC'] and 'msvs_projects' in targets
38
39
40 # now, if rebuild_targets is specified, do not rebuild some targets
41 rebuild_targets = env['REBUILD_TARGETS']
42 if rebuild_targets:
43   def ifBuildLib(name, libname, old_value):
44     # explicitly asked to rebuild
45     if name in rebuild_targets:
46       return True
47     # else if not rebuild, and if the library already exists
48     elif os.path.isfile(File(env.subst('$LOCALLIBPATH/${LIBPREFIX}%s$LIBSUFFIX'%libname)).abspath):
49       return False
50     # do not change the original value
51     else:
52       return old_value
53   build_boost = ifBuildLib('boost', 'included_boost_filesystem', build_boost)
54   build_intl = ifBuildLib('intl', 'included_intl', build_intl)
55   build_support = ifBuildLib('support', 'support', build_support)
56   build_mathed = ifBuildLib('mathed', 'mathed', build_mathed)
57   build_insets = ifBuildLib('insets', 'insets', build_insets)
58   build_frontends = ifBuildLib('frontends', 'frontends', build_frontends)
59   build_graphics = ifBuildLib('graphics', 'graphics', build_graphics)
60   build_controllers = ifBuildLib('controllers', 'controllers', build_controllers)
61   build_lyxbase = ifBuildLib('lyxbase', 'lyxbase_pre', build_lyxbase)
62   build_qt3 = ifBuildLib('qt3', 'qt3', build_qt3)
63   build_qt4 = ifBuildLib('qt4', 'qt4', build_qt4)
64
65 # sync frontend and env['frontend'] (maybe build qt4 with frontend=qt3)
66 if build_qt3:
67   frontend = 'qt3'
68   env['frontend'] = 'qt3'
69 elif build_qt4:
70   frontend = 'qt4'
71   env['frontend'] = 'qt4'
72 else:
73   frontend = env['frontend']
74
75
76 if build_boost:
77   #
78   # boost libraries
79   #
80   # special builddir
81   env.BuildDir('$BUILDDIR/boost', '$TOP_SRC_DIR/boost/libs', duplicate = 0)
82
83   boostenv = env.Copy()
84   boostenv.AppendUnique(CCFLAGS = '-DBOOST_USER_CONFIG="<config.h>"')
85
86   print 'Processing files in boost/libs/filesystem/src...'
87
88   filesystem = boostenv.StaticLibrary(
89     target = '$LOCALLIBPATH/included_boost_filesystem',
90     source = globSource(dir = env.subst('$TOP_SRC_DIR/boost/libs/filesystem/src'), 
91       pattern = '*.cpp', build_dir = '$BUILDDIR/boost/filesystem/src')
92   )
93
94   print 'Processing files in boost/libs/regex/src...'
95
96   regex = boostenv.StaticLibrary(
97     target = '$LOCALLIBPATH/included_boost_regex',
98     source = globSource(dir = env.subst('$TOP_SRC_DIR/boost/libs/regex/src'), 
99       pattern = '*.cpp', build_dir = '$BUILDDIR/boost/regex/src')
100   )
101
102   print 'Processing files in boost/libs/signals/src...'
103
104   signals = boostenv.StaticLibrary(
105     target = '$LOCALLIBPATH/included_boost_signals',
106     source = globSource(dir = env.subst('$TOP_SRC_DIR/boost/libs/signals/src'), 
107       pattern = '*.cpp', build_dir = '$BUILDDIR/boost/signals/src')
108   )
109
110   print 'Processing files in boost/libs/iostreams/src...'
111
112   iostreams = boostenv.StaticLibrary(
113     target = '$LOCALLIBPATH/included_boost_iostreams',
114     source = globSource(dir = env.subst('$TOP_SRC_DIR/boost/libs/iostreams/src'), 
115       pattern = '*.cpp', build_dir = '$BUILDDIR/boost/iostreams/src')
116   )
117   Alias('boost', filesystem)
118   Alias('boost', regex)
119   Alias('boost', signals)
120   Alias('boost', iostreams)
121
122
123 if build_intl:
124   # 
125   # intl
126   # 
127   print "Processing files in intl..."
128
129   env.BuildDir('$BUILDDIR/intl', '$TOP_SRC_DIR/intl', duplicate = 0)
130
131   intlenv = env.Copy()
132   # we need the original C compiler for these files
133   intlenv['CC'] = intlenv['C_COMPILER']
134   intlenv['CCFLAGS'] = intlenv['C_CCFLAGS']
135   intlenv['CPPPATH'] += ['intl']
136   
137   intlenv.Append(CCFLAGS = [
138     r'-DLOCALEDIR=\"' + env['LOCALE_DIR'].replace('\\', '\\\\') + r'\"',
139     r'-DLOCALE_ALIAS_PATH=\"' + env['LOCALE_DIR'].replace('\\', '\\\\') + r'\"',
140     r'-DLIBDIR=\"' + env['TOP_SRC_DIR'].replace('\\', '\\\\') + r'/lib\"',
141     '-DIN_LIBINTL',
142     '-DENABLE_RELOCATABLE=1',
143     '-DIN_LIBRARY',
144     r'-DINSTALLDIR=\"' + env['PREFIX'].replace('\\', '\\\\') + r'/lib\"',
145     '-DNO_XMALLOC',
146     '-Dset_relocation_prefix=libintl_set_relocation_prefix',
147     '-Drelocate=libintl_relocate',
148     '-DDEPENDS_ON_LIBICONV=1',
149     '-DHAVE_CONFIG_H'
150     ]
151   )
152
153   # libgnuintl.h.in => libintl.h
154   env.substFile('$TOP_SRC_DIR/intl/libintl.h', '$TOP_SRC_DIR/intl/libgnuintl.h.in')
155   env.Command('$TOP_SRC_DIR/intl/libgnuintl.h', '$TOP_SRC_DIR/intl/libintl.h',
156       [Copy('$TARGET', '$SOURCE')])
157   
158   intl = intlenv.StaticLibrary(
159     target = '$LOCALLIBPATH/included_intl',
160     LIBS = ['c'],
161     source = globSource(dir = env.subst('$TOP_SRC_DIR/intl'), pattern = '*.c',
162       exclude = ['vasnprintf.c', 'printf-parse.c', 'printf-args.c', 'os2compat.c'],
163       build_dir = '$BUILDDIR/intl')
164   )
165   Alias('intl', intl)
166
167
168 #
169 # Now, src code under src/
170 #
171 env.BuildDir('$BUILDDIR/common', '$TOP_SRC_DIR/src', duplicate = 0)
172
173
174 if build_support:
175   #
176   # src/support
177   #
178   print "Processing files in src/support..."
179
180   env.substFile('$BUILDDIR/common/support/package.C', '$TOP_SRC_DIR/src/support/package.C.in')
181
182   support = env.StaticLibrary(
183     target = '$LOCALLIBPATH/support',
184     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/support'), pattern = env['LYX_EXT'], 
185       exclude = ['os_win32.C', 'os_unix.C', 'os_cygwin.C', 'atexit.c'],
186       include = ['package.C'], build_dir = '$BUILDDIR/common/support')
187   )
188   Alias('support', support)
189
190
191 if build_mathed:
192   #
193   # src/mathed
194   #
195   print "Processing files in src/mathed..."
196
197   mathed = env.StaticLibrary(
198     target = '$LOCALLIBPATH/mathed',
199     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/mathed'), pattern = env['LYX_EXT'],
200       exclude = ['math_xyarrowinset.C', 'math_mboxinset.C', 'formulamacro.C'],
201       build_dir = '$BUILDDIR/common/mathed')
202   )
203   Alias('mathed', mathed)
204
205
206 if build_insets:
207   #
208   # src/insets
209   #
210   print "Processing files in src/insets..."
211
212   insets = env.StaticLibrary(
213     target = '$LOCALLIBPATH/insets',
214     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/insets'), pattern = env['LYX_EXT'],
215       exclude = ['insettheorem.C'], build_dir = '$BUILDDIR/common/insets')
216   )
217   Alias('insets', insets)
218
219
220 if build_frontends:
221   #
222   # src/frontends
223   #
224   print "Processing files in src/frontends..."
225
226   frontends = env.StaticLibrary(
227     target = '$LOCALLIBPATH/frontends',
228     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends'), pattern = env['LYX_EXT'],
229       build_dir = '$BUILDDIR/common/frontends')
230   )
231   Alias('frontends', frontends)
232
233
234 if build_graphics:
235   #
236   # src/graphics
237   #
238   print "Processing files in src/graphics..."
239
240   graphics = env.StaticLibrary(
241     target = '$LOCALLIBPATH/graphics',
242     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/graphics'), pattern = env['LYX_EXT'],
243       build_dir = '$BUILDDIR/common/graphics')
244   )
245   Alias('graphics', graphics)
246
247
248 if build_controllers:
249   #
250   # src/frontends/controllers
251   #
252   print "Processing files in src/frontends/controllers..."
253
254   controllers = env.StaticLibrary(
255     target = '$LOCALLIBPATH/controllers',
256     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends/controllers'), pattern = env['LYX_EXT'],
257       build_dir = '$BUILDDIR/common/frontends/controllers')
258   )
259   Alias('controllers', controllers)
260
261
262 #
263 # src/frontend/qt3/4
264 #
265 if build_qt3 or build_qt4:
266   env.BuildDir('$BUILDDIR/$frontend', '$TOP_SRC_DIR/src/frontend/$frontend', duplicate = 0)
267
268 if build_qt3:
269   print "Processing files in src/frontends/qt3..."
270
271   qt3env = env.Copy()
272   # disable auto scan to speed up non build time
273   qt3env['QT_AUTOSCAN'] = 0
274   qt3env['QT_MOCHPREFIX'] = ''
275
276   # load qt3 tools
277   qt3env.Tool('qt')
278
279   qt3env.AppendUnique(CPPPATH = [
280     '$BUILDDIR/common',
281     '$BUILDDIR/common/images',
282     '$BUILDDIR/common/frontends',
283     '$BUILDDIR/common/frontends/qt3',
284     '$BUILDDIR/common/frontends/controllers',
285     '$QT_INC_PATH']
286   )
287
288   qt3_moc_files = ["$BUILDDIR/common/frontends/qt3/%s" % x for x in Split('''
289     BulletsModule.C
290     emptytable.C
291     FileDialog_private.C
292     floatplacement.C
293     iconpalette.C
294     lengthcombo.C
295     panelstack.C
296     QAboutDialog.C
297     QBibitemDialog.C
298     QBibtexDialog.C
299     QBoxDialog.C
300     QBranchDialog.C
301     QBrowseBox.C
302     QChangesDialog.C
303     QCharacterDialog.C
304     QCitationDialog.C
305     QCommandBuffer.C
306     QCommandEdit.C
307     QContentPane.C
308     QDelimiterDialog.C
309     QDocumentDialog.C
310     QErrorListDialog.C
311     QERTDialog.C
312     QExternalDialog.C
313     QFloatDialog.C
314     QGraphicsDialog.C
315     QIncludeDialog.C
316     QIndexDialog.C
317     QLogDialog.C
318     QViewSourceDialog.C
319     QLPopupMenu.C
320     QLPrintDialog.C
321     QMathDialog.C
322     QMathMatrixDialog.C
323     QNoteDialog.C
324     QParagraphDialog.C
325     QPrefsDialog.C
326     QRefDialog.C
327     QSearchDialog.C
328     QSendtoDialog.C
329     qsetborder.C
330     QShowFileDialog.C
331     QSpellcheckerDialog.C
332     QDialogView.C
333     QTabularCreateDialog.C
334     QTabularDialog.C
335     QTexinfoDialog.C
336     QThesaurusDialog.C
337     QTocDialog.C
338     qttableview.C
339     QtView.C
340     QURLDialog.C
341     QVSpaceDialog.C
342     QWrapDialog.C
343     QLToolbar.C
344     socket_callback.C
345     validators.C
346   ''')]
347
348   # manually moc and uic files for better performance 
349   qt3_moced_files = [qt3env.Moc(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt3_moc_files]
350
351   qt3_uiced_files = [qt3env.Uic('$BUILDDIR/common/frontends/qt3/ui/'+x) for x in \
352      globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends/qt3/ui'), pattern = '*.ui')]
353
354   qt3_uiced_cc_files = []
355   for x in qt3_uiced_files:
356     qt3_uiced_cc_files.extend(x[1:])
357
358   qt3 = qt3env.StaticLibrary(
359     target = '$LOCALLIBPATH/qt3',
360     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends/qt3/'), pattern = env['LYX_EXT'],
361       build_dir = '$BUILDDIR/common/frontends/qt3') + qt3_moced_files + qt3_uiced_cc_files
362   )
363   Alias('qt3', qt3)
364
365
366 if build_qt4:
367   print "Processing files in src/frontends/qt4..."
368
369   qt4env = env.Copy()
370   qt4env['QT_AUTOSCAN'] = 0
371
372   # local qt4 toolset from
373   # http://www.iua.upf.es/~dgarcia/Codders/sconstools.html
374   #
375   # NOTE: I have to patch qt4.py since it does not automatically
376   # process .C file!!! (add to cxx_suffixes )
377   #
378   qt4env.Tool('qt4', [env['SCONS_DIR']])
379   qt4env.EnableQt4Modules(env['QT_LIB'], debug = False)
380
381   qt4env.AppendUnique(CPPPATH = [
382     '$BUILDDIR/common',
383     '$BUILDDIR/common/images',
384     '$BUILDDIR/common/frontends',
385     '$BUILDDIR/common/frontends/qt4',
386     '$BUILDDIR/common/frontends/controllers' 
387     ]
388   )
389
390   # FIXME: replace by something from pkg_config
391   qt4env.Append(CCFLAGS = [
392     '-DHAVE_CONFIG_H',
393     '-DQT_CLEAN_NAMESPACE',
394     '-DQT_GENUINE_STR',
395     '-DQT_NO_STL',
396     '-DQT3_SUPPORT',
397     ]
398   )
399
400
401   qt4_moc_files = ["$BUILDDIR/common/frontends/qt4/%s" % x for x in Split('''
402     BulletsModule.C
403     emptytable.C
404     FileDialog_private.C
405     floatplacement.C
406     iconpalette.C
407     lengthcombo.C
408     InsertTableWidget.C
409     panelstack.C
410     QAboutDialog.C
411     QBibitemDialog.C
412     QBibtexDialog.C
413     QBoxDialog.C
414     QBranchDialog.C
415     QBranches.C
416     QChangesDialog.C
417     QCharacterDialog.C
418     QCitationDialog.C
419     QCommandBuffer.C
420     QCommandEdit.C
421     QDelimiterDialog.C
422     QDocumentDialog.C
423     QErrorListDialog.C
424     QERTDialog.C
425     QExternalDialog.C
426     QFloatDialog.C
427     QGraphicsDialog.C
428     QIncludeDialog.C
429     QIndexDialog.C
430     QLAction.C
431     QLogDialog.C
432     QViewSourceDialog.C
433     QViewSource.C
434     QLMenubar.C
435     QLPopupMenu.C
436     QLPrintDialog.C
437     QMathDialog.C
438     QMathMatrixDialog.C
439     QNoteDialog.C
440     QParagraphDialog.C
441     QPrefsDialog.C
442     QRefDialog.C
443     QSearchDialog.C
444     QSendtoDialog.C
445     qsetborder.C
446     QShowFileDialog.C
447     QSpellcheckerDialog.C
448     QDialogView.C
449     QTabularCreateDialog.C
450     QTabularDialog.C
451     QTexinfoDialog.C
452     QThesaurusDialog.C
453     TocModel.C
454     QTocDialog.C
455     QtView.C
456     QURLDialog.C
457     QVSpaceDialog.C
458     QWorkArea.C
459     QWrapDialog.C
460     QLToolbar.C
461     socket_callback.C
462     validators.C
463   ''') ]
464
465   #
466   # Compile resources
467   #
468   resources = [qt4env.Uic4(x.split('.')[0]) for x in \
469     globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends/qt4/ui'), pattern = '*.ui',
470       build_dir = '$BUILDDIR/common/frontends/qt4/ui')]
471
472   # 
473   # moc qt4_moc_files, the moced files are included in the original files
474   #
475   qt4_moced_files = [qt4env.Moc4(x.replace('.C', '_moc.cpp'), x.replace('.C', '.h')) for x in qt4_moc_files]
476
477   qt4 = qt4env.StaticLibrary(
478     target = '$LOCALLIBPATH/qt4',
479     LIBS = qt4env['QT_LIB'],
480     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/frontends/qt4'), pattern = env['LYX_EXT'],
481       exclude = ['QBrowseBox.C'], build_dir = '$BUILDDIR/common/frontends/qt4')
482   )
483   Alias('qt4', qt4)
484
485
486 if build_client:
487   #
488   # src/client
489   #
490   env.BuildDir('$BUILDDIR/common', '$TOP_SRC_DIR/src', duplicate = 0)
491
492   print "Processing files in src/client..."
493
494   if env['HAVE_FCNTL']:
495     client = env.Program(
496       target = '$BUILDDIR/common/client/lyxclient',
497       LIBS = ['support'] + env['INTL_LIBS'] + env['SYSTEM_LIBS'] + 
498         env['SOCKET_LIBS'] + env['BOOST_LIBRARIES'],
499       source = globSource(dir = env.subst('$TOP_SRC_DIR/src/client'), pattern = env['LYX_EXT'],
500         build_dir = '$BUILDDIR/common/client')
501     )
502     Alias('client', env.Command(os.path.join('$BUILDDIR', os.path.split(str(client[0]))[1]),
503       client, [Copy('$TARGET', '$SOURCE')]))
504   else:
505     client = None
506   Alias('client', client)
507
508
509 if build_tex2lyx:
510   #
511   # tex2lyx
512   #
513   print "Processing files in src/tex2lyx..."
514
515   tex2lyx_env = env.Copy()
516   # the order is important here.
517   tex2lyx_env.Prepend(CPPPATH = ['$BUILDDIR/common/tex2lyx'])
518   tex2lyx_env.AppendUnique(LIBPATH = ['#$LOCALLIBPATH'])
519
520   for file in ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.h', 'lyxlayout.C', 
521     'lyxtextclass.h', 'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C']:
522     env.Command('$BUILDDIR/common/tex2lyx/'+file, '$TOP_SRC_DIR/src/'+file,
523       [Copy('$TARGET', '$SOURCE')])
524
525   tex2lyx = tex2lyx_env.Program(
526     target = '$BUILDDIR/common/tex2lyx/tex2lyx',
527     LIBS = ['support'] + env['BOOST_LIBRARIES'] + env['SYSTEM_LIBS'],
528     source = globSource(dir = env.subst('$TOP_SRC_DIR/src/tex2lyx'), pattern = env['LYX_EXT'], 
529       include = ['FloatList.C', 'Floating.C', 'counters.C', 'lyxlayout.C', 
530         'lyxtextclass.C', 'lyxlex.C', 'lyxlex_pimpl.C'],
531       build_dir = '$BUILDDIR/common/tex2lyx')
532   )
533   Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', os.path.split(str(tex2lyx[0]))[1]),
534     tex2lyx, [Copy('$TARGET', '$SOURCE')]))
535   Alias('tex2lyx', tex2lyx)
536
537
538 if build_lyxbase:
539   #
540   # src/
541   #
542   print "Processing files in src..."
543
544   env.substFile('$BUILDDIR/common/version.C', '$TOP_SRC_DIR/src/version.C.in')
545
546   lyx_post_source = Split('''
547     tabular.C
548     dimension.C
549     PrinterParams.C
550     box.C
551     Thesaurus.C
552     SpellBase.C
553   ''')
554
555   if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
556     lyx_post_source.append('aspell.C')
557   elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
558     lyx_post_source.append('pspell.C')
559   elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
560     lyx_post_source.append('ispell.C')
561
562   # temporary fix for MSVC, will remove later.
563   if not env['USE_VC']:
564     main_source = ['main.C']
565   else:
566     main_source = []
567
568   lyxbase_pre = env.StaticLibrary(
569     target = '$LOCALLIBPATH/lyxbase_pre',
570     source = globSource(dir = env.subst('$TOP_SRC_DIR/src'), pattern = env['LYX_EXT'], 
571       exclude = lyx_post_source + ['main.C', 'aspell.C', 'pspell.C', 'ispell.C', 'Variables.C', 'Sectioning.C'],
572       include = ['version.C'] + main_source, build_dir = '$BUILDDIR/common')
573   )
574   lyxbase_post = env.StaticLibrary(
575     target = '$LOCALLIBPATH/lyxbase_post',
576     source = ["$BUILDDIR/common/%s" % x for x in lyx_post_source]
577   )
578   Alias('lyxbase', lyxbase_pre)
579   Alias('lyxbase', lyxbase_post)
580
581
582 if build_lyx:
583   #
584   # Build lyx with given frontend
585   #
586   # temporary fix for MSVC, will remove later.
587   if env['USE_VC']:
588     lyx_source = ['$BUILDDIR/common/main.C']
589   else:
590     lyx_source = []
591   lyx = env.Program(
592     target = '$BUILDDIR/$frontend/lyx',
593     source = lyx_source,
594     LIBS = [
595       'lyxbase_pre',
596       'mathed',
597       'insets',
598       'frontends',
599       env['frontend'],
600       'controllers',
601       'graphics',
602       'support',
603       'lyxbase_post',
604       ] +
605       env['BOOST_LIBRARIES'] +
606       env['FRONTEND_LIBS'] +
607       env['INTL_LIBS'] + 
608       env['SOCKET_LIBS'] +
609       env['SYSTEM_LIBS']
610   )
611   # [/path/to/lyx.ext] => lyx-qt3.ext
612   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s' % frontend)
613   Alias('lyx', env.Command(os.path.join('$BUILDDIR', target_name), lyx,
614     [Copy('$TARGET', '$SOURCE')]))
615   Alias('lyx', lyx)
616
617
618 if build_msvs_projects:
619   def build_project(target, dir, full_target = None, 
620     src_pattern = env['LYX_EXT'], include=[], resource=None, rebuild=True):
621     ''' build mavs project files 
622       target:      alias (correspond to directory name)
623       dir:         source directory or directories (a list)
624       full_target: full path/filename of the target
625       src_pattern: glob pattern
626       include:     files to include into source
627       resource:    directory or directories with resource (.ui) files
628       rebuild:     whether or not only rebuild this target
629
630     For non-debug-able targets like static libraries, target (alias) is 
631     enough to build the target. For executable targets, msvs need to know
632     the full path to start debug them.
633     '''
634     if resource is not None:
635       res = globSource(dir = env.subst('$TOP_SRC_DIR/'+resource), pattern = '*.ui', 
636         build_dir = env.subst('$TOP_SRC_DIR/'+resource))
637     else:
638       res = []
639     if rebuild:
640       cmds = 'faststart=yes rebuild='+target
641     else:
642       cmds = 'faststart=yes'
643     if type(dir) == type([]):
644       src = []
645       inc = []
646       for d in dir:
647         src.extend(globSource(dir = env.subst('$TOP_SRC_DIR/' + d), 
648           pattern = src_pattern, include = include,
649           build_dir = env.subst('$TOP_SRC_DIR/' + d) ))
650         inc.extend(globSource(dir = env.subst('$TOP_SRC_DIR/' + d), 
651           pattern = '*.h', 
652           build_dir = env.subst('$TOP_SRC_DIR/' + d) ))
653     else:
654       src = globSource(dir = env.subst('$TOP_SRC_DIR/' + dir), 
655         pattern = src_pattern, include = include,
656         build_dir = env.subst('$TOP_SRC_DIR/' + dir) )
657       inc = globSource(dir = env.subst('$TOP_SRC_DIR/' + dir), 
658         pattern = '*.h', 
659         build_dir = env.subst('$TOP_SRC_DIR/' + dir) )
660     if full_target is None:
661       build_target = target
662     else:
663       build_target = full_target
664     # project
665     proj = env.MSVSProject(
666       target = '$MSVSPATH/' + target + env['MSVSPROJECTSUFFIX'],
667       srcs = src,
668       incs = [env.subst('$TOP_SRC_DIR/src/config.h')],
669       localincs = inc,
670       resources = res,
671       buildtarget = build_target,
672       cmdargs = cmds,
673       variant = 'Debug'
674     )
675     Alias('msvs_projects', proj)
676   #
677   build_project('boost', ['boost/libs/filesystem/src',
678     'boost/libs/regex/src', 'boost/libs/signals/src',
679     'boost/libs/iostreams/src'], src_pattern = '*.cpp')
680   #
681   build_project('intl', 'intl', src_pattern = '*.c')
682   #
683   build_project('support', 'src/support', include=['package.C.in'])
684   #
685   build_project('mathed', 'src/mathed')
686   #
687   build_project('insets', 'src/insets')
688   #
689   build_project('frontends', 'src/frontends')
690   #
691   build_project('graphics', 'src/graphics')
692   #
693   build_project('controllers', 'src/frontends/controllers')
694   #
695   build_project('qt3', 'src/frontends/qt3', resource = 'src/frontends/qt3/ui')
696   #
697   build_project('qt4', 'src/frontends/qt4', resource = 'src/frontends/qt4/ui')
698   #
699   build_project('client', 'src/client', rebuild=False, 
700     full_target = File(env.subst('$BUILDDIR/common/client/lyxclient$PROGSUFFIX')).abspath)
701   #
702   build_project('tex2lyx', 'src/tex2lyx', rebuild=False,
703     full_target = File(env.subst('$BUILDDIR/common/tex2lyx/tex2lyx$PROGSUFFIX')).abspath)
704   #
705   build_project('lyxbase', 'src')
706   #
707   if frontend == 'qt3':
708     build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
709       'src/frontends', 'src/graphics', 'src/frontends/controllers', 
710       'src/frontends/qt3'], resource = 'src/frontends/qt3/ui',
711       full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
712   else:
713     build_project('lyx', ['src', 'src/support', 'src/mathed', 'src/insets',
714       'src/frontends', 'src/graphics', 'src/frontends/controllers', 
715       'src/frontends/qt4'], resource = 'src/frontends/qt4/ui',
716       full_target = File(env.subst('$BUILDDIR/$frontend/lyx$PROGSUFFIX')).abspath)
717
718
719 if build_po:
720   #
721   # po/
722   #
723   print 'Processing files in po...'
724
725   import glob
726   # handle po files
727   #
728   # files to translate
729   transfiles = glob.glob(os.path.join(env.subst('$TOP_SRC_DIR'), 'po', '*.po'))
730   # possibly *only* handle these languages
731   languages = None
732   if env.has_key('languages'):
733     languages = env.make_list(env['lanauges'])
734   # use defulat msgfmt
735   if not env['MSGFMT']:
736     print 'msgfmt does not exist. Can not process po files'
737   else:
738     # create a builder
739     env['BUILDERS']['Transfiles'] = Builder(action='$MSGFMT $SOURCE -o $TARGET',suffix='.gmo',src_suffix='.po')
740     #
741     gmo_files = []
742     for f in transfiles:
743       # get filename
744       fname = os.path.split(f)[1]
745       # country code
746       country = fname.split('.')[0]
747       #
748       if not languages or country in languages:
749         gmo_files.extend(env.Transfiles(f))
750
751
752 if 'install' in targets:
753   # create the directory if needed
754   if not os.path.isdir(env['DEST_DIR']):
755     try:
756       os.makedirs(env['DEST_DIR'])
757     except:
758       pass
759     if not os.path.isdir(env['DEST_DIR']):
760       print 'Can not create directory', env['DEST_DIR']
761       Exit(3)
762   #
763   import glob
764   #
765   # do not install these files
766   exclude_list = ['Makefile.am', 'Makefile.in', 'Makefile', 
767     'lyx2lyx_version.py', 'lyx2lyx_version.py.in']
768
769   def install(dest, src):
770     ''' recusive installation of src to dest '''
771     # separate file and directory
772     files = filter(lambda x: os.path.isfile(x) and not os.path.split(x)[1] in exclude_list, src)
773     dirs = filter(os.path.isdir, src)
774     # install file
775     env.Install(dest, files)
776     # install directory
777     ins_dir = [dest]
778     for dir in dirs:
779       ins_dir.extend(install(os.path.join(dest, os.path.basename(dir)),
780         glob.glob(os.path.join(dir, '*'))) )
781     return ins_dir
782   #
783   # executables (some of them may be none)
784   #
785   if env['ADD_SUFFIX']:
786     version_suffix = env['PROGRAM_SUFFIX']
787   else:
788     version_suffix = ''
789   #
790   # install lyx
791   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx%s' % version_suffix)
792   target = os.path.join(env['BIN_DEST_DIR'], target_name)
793   env.InstallAs(target, lyx)
794   Alias('install', target)
795   # install lyx as lyx-qt3
796   target_name = os.path.split(str(lyx[0]))[1].replace('lyx', 'lyx-%s%s' % (frontend, version_suffix))
797   target = os.path.join(env['BIN_DEST_DIR'], target_name)
798   env.InstallAs(target, lyx)
799   Alias('install', target)
800   #
801   # install tex2lyx
802   target_name = os.path.split(str(tex2lyx[0]))[1].replace('tex2lyx', 'tex2lyx%s' % version_suffix)
803   target = os.path.join(env['BIN_DEST_DIR'], target_name)
804   env.InstallAs(target, tex2lyx)
805   Alias('install', target)
806   #
807   # install lyxclient, may not exist
808   if client != None:
809     target_name = os.path.split(str(client[0]))[1].replace('client', 'client%s' % version_suffix)
810     target = os.path.join(env['BIN_DEST_DIR'], target_name)
811     env.InstallAs(target, client)
812     Alias('install', target)
813   #
814   # share/lyx
815   dirs = install(env['SHARE_DEST_DIR'],
816     [env.subst('$TOP_SRC_DIR/lib/') + file for file in ['configure.py', 'encodings',
817      'chkconfig.ltx', 'CREDITS', 'external_templates', 'symbols', 'languages',
818      'lyxrc.example', 'syntax.default', 'bind', 'images', 'layouts', 'scripts', 
819      'templates', 'examples', 'kbd', 'lyx2lyx', 'tex', 'clipart', 'doc',  'ui']]
820   )
821   env.substFile('$SHARE_DEST_DIR/lyx2lyx/lyx2lyx_version.py', 
822     '$TOP_SRC_DIR/lib/lyx2lyx/lyx2lyx_version.py.in')
823   Alias('install', dirs)
824   # man
825   env.InstallAs(os.path.join(env['MAN_DEST_DIR'], 'lyx' + version_suffix + '.1'),
826     env.subst('$TOP_SRC_DIR/lyx.man'))
827   env.InstallAs(os.path.join(env['MAN_DEST_DIR'], 'tex2lyx' + version_suffix + '.1'),
828     env.subst('$TOP_SRC_DIR/src/tex2lyx/tex2lyx.man'))
829   env.InstallAs(os.path.join(env['MAN_DEST_DIR'], 'lyxclient' + version_suffix + '.1'),
830     env.subst('$TOP_SRC_DIR/src/client/lyxclient.man'))
831   Alias('install', [os.path.join(env['MAN_DEST_DIR'], x + version_suffix + '.1') for
832     x in ['lyx', 'tex2lyx', 'lyxclient']])
833   # locale files?
834   # ru.gmo ==> ru/LC_MESSAGES/lyxSUFFIX.mo
835   for gmo in gmo_files:
836     lan = os.path.split(str(gmo))[1].split('.')[0]
837     dest_file = os.path.join(env['LOCALE_DEST_DIR'], lan, 'LC_MESSAGES', 'lyx' + version_suffix + '.mo')
838     env.InstallAs(dest_file, gmo)
839     Alias('install', dest_file)
840
841
842 Default('lyx')
843 Alias('all', ['lyx', 'client', 'tex2lyx'])