Merge pull request #239 from peter-scholtens/master
[geany-mirror.git] / wscript
blob1b12bf007cd14f587b3bbc509382b2973b011870
1 # -*- coding: utf-8 -*-
3 # WAF build script - this file is part of Geany, a fast and lightweight IDE
5 # Copyright 2008-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
6 # Copyright 2008-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 """
23 This is a WAF build script (http://code.google.com/p/waf/).
24 It can be used as an alternative build system to autotools
25 for Geany. It does not (yet) cover all of the autotools tests and
26 configure options but all important things are working.
27 "make dist" should be done with autotools, most other targets and
28 functions should work better (regarding performance and flexibility)
29 or at least equally.
31 Missing features: --enable-binreloc, make targets: dist, pdf (in doc/)
32 Known issues: Dependency handling is buggy, e.g. if src/document.h is
33               changed, depending source files are not rebuilt (maybe Waf bug).
35 The code of this file itself loosely follows PEP 8 with some exceptions
36 (line width 100 characters and some other minor things).
38 Requires WAF 1.6.1 and Python 2.5 (or later).
39 """
42 import sys
43 import os
44 import tempfile
45 from waflib import Logs, Options, Scripting, Utils
46 from waflib.Configure import ConfigurationContext
47 from waflib.Errors import WafError
48 from waflib.TaskGen import feature, before_method
49 from waflib.Tools.compiler_c import c_compiler
50 from waflib.Tools.compiler_cxx import cxx_compiler
53 APPNAME = 'geany'
54 VERSION = '1.24'
55 LINGUAS_FILE = 'po/LINGUAS'
56 MINIMUM_GTK_VERSION = '2.16.0'
57 MINIMUM_GTK3_VERSION = '3.0.0'
58 MINIMUM_GLIB_VERSION = '2.20.0'
60 top = '.'
61 out = '_build_'
64 mio_sources = set(['tagmanager/mio/mio.c'])
66 ctags_sources = set([
67     'tagmanager/ctags/abaqus.c',
68     'tagmanager/ctags/args.c',
69     'tagmanager/ctags/abc.c',
70     'tagmanager/ctags/actionscript.c',
71     'tagmanager/ctags/asciidoc.c',
72     'tagmanager/ctags/asm.c',
73     'tagmanager/ctags/basic.c',
74     'tagmanager/ctags/c.c',
75     'tagmanager/ctags/cobol.c',
76     'tagmanager/ctags/conf.c',
77     'tagmanager/ctags/css.c',
78     'tagmanager/ctags/ctags.c',
79     'tagmanager/ctags/diff.c',
80     'tagmanager/ctags/docbook.c',
81     'tagmanager/ctags/entry.c',
82     'tagmanager/ctags/fortran.c',
83     'tagmanager/ctags/get.c',
84     'tagmanager/ctags/haskell.c',
85     'tagmanager/ctags/haxe.c',
86     'tagmanager/ctags/html.c',
87     'tagmanager/ctags/js.c',
88     'tagmanager/ctags/keyword.c',
89     'tagmanager/ctags/latex.c',
90     'tagmanager/ctags/lregex.c',
91     'tagmanager/ctags/lua.c',
92     'tagmanager/ctags/make.c',
93     'tagmanager/ctags/markdown.c',
94     'tagmanager/ctags/matlab.c',
95     'tagmanager/ctags/nsis.c',
96     'tagmanager/ctags/nestlevel.c',
97     'tagmanager/ctags/objc.c',
98     'tagmanager/ctags/options.c',
99     'tagmanager/ctags/parse.c',
100     'tagmanager/ctags/pascal.c',
101     'tagmanager/ctags/r.c',
102     'tagmanager/ctags/perl.c',
103     'tagmanager/ctags/php.c',
104     'tagmanager/ctags/python.c',
105     'tagmanager/ctags/read.c',
106     'tagmanager/ctags/rest.c',
107     'tagmanager/ctags/ruby.c',
108     'tagmanager/ctags/rust.c',
109     'tagmanager/ctags/sh.c',
110     'tagmanager/ctags/sort.c',
111     'tagmanager/ctags/sql.c',
112     'tagmanager/ctags/strlist.c',
113     'tagmanager/ctags/txt2tags.c',
114     'tagmanager/ctags/tcl.c',
115     'tagmanager/ctags/vhdl.c',
116     'tagmanager/ctags/verilog.c',
117     'tagmanager/ctags/vstring.c'])
119 tagmanager_sources = set([
120     'tagmanager/src/tm_file_entry.c',
121     'tagmanager/src/tm_project.c',
122     'tagmanager/src/tm_source_file.c',
123     'tagmanager/src/tm_symbol.c',
124     'tagmanager/src/tm_tag.c',
125     'tagmanager/src/tm_tagmanager.c',
126     'tagmanager/src/tm_work_object.c',
127     'tagmanager/src/tm_workspace.c'])
129 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
131 geany_sources = set([
132     'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
133     'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
134     'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
135     'src/highlighting.c', 'src/keybindings.c',
136     'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
137     'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
138     'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
139     'src/symbols.c',
140     'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
141     'src/ui_utils.c', 'src/utils.c'])
143 geany_icons = {
144     'hicolor/16x16/apps':       ['16x16/classviewer-class.png',
145                                  '16x16/classviewer-macro.png',
146                                  '16x16/classviewer-member.png',
147                                  '16x16/classviewer-method.png',
148                                  '16x16/classviewer-namespace.png',
149                                  '16x16/classviewer-other.png',
150                                  '16x16/classviewer-struct.png',
151                                  '16x16/classviewer-var.png',
152                                  '16x16/geany.png'],
153     'hicolor/16x16/actions':    ['16x16/geany-build.png',
154                                  '16x16/geany-close-all.png',
155                                  '16x16/geany-save-all.png'],
156     'hicolor/24x24/actions':    ['24x24/geany-build.png',
157                                  '24x24/geany-close-all.png',
158                                  '24x24/geany-save-all.png'],
159     'hicolor/32x32/actions':    ['32x32/geany-build.png',
160                                  '32x32/geany-close-all.png',
161                                  '32x32/geany-save-all.png'],
162     'hicolor/48x48/actions':    ['48x48/geany-build.png',
163                                  '48x48/geany-close-all.png',
164                                  '48x48/geany-save-all.png'],
165     'hicolor/48x48/apps':       ['48x48/geany.png'],
166     'hicolor/scalable/apps':    ['scalable/geany.svg'],
167     'hicolor/scalable/actions': ['scalable/geany-build.svg',
168                                  'scalable/geany-close-all.svg',
169                                  'scalable/geany-save-all.svg'],
170     'Tango/16x16/actions':      ['tango/16x16/geany-save-all.png'],
171     'Tango/24x24/actions':      ['tango/24x24/geany-save-all.png'],
172     'Tango/32x32/actions':      ['tango/32x32/geany-save-all.png'],
173     'Tango/48x48/actions':      ['tango/48x48/geany-save-all.png'],
174     'Tango/scalable/actions':   ['tango/scalable/geany-save-all.svg']
176 geany_icons_indexes = {
177     'hicolor':  ['index.theme'],
178     'Tango':    ['tango/index.theme']
182 def configure(conf):
184     conf.check_waf_version(mini='1.6.1')
186     conf.load('compiler_c')
187     is_win32 = _target_is_win32(conf)
189     conf.check_cc(header_name='fcntl.h', mandatory=False)
190     conf.check_cc(header_name='fnmatch.h', mandatory=False)
191     conf.check_cc(header_name='glob.h', mandatory=False)
192     conf.check_cc(header_name='sys/time.h', mandatory=False)
193     conf.check_cc(header_name='sys/types.h', mandatory=False)
194     conf.check_cc(header_name='sys/stat.h', mandatory=False)
195     conf.define('HAVE_STDLIB_H', 1)  # are there systems without stdlib.h?
196     conf.define('STDC_HEADERS', 1)  # an optimistic guess ;-)
197     _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)  # needed for CTags
199     conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
200     conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
201     conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
202     conf.check_cc(function_name='strstr', header_name='string.h')
204     # check sunOS socket support
205     if Options.platform == 'sunos':
206         conf.check_cc(function_name='socket', lib='socket',
207                       header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
209     # check for cxx after the header and function checks have been done to ensure they are
210     # checked with cc not cxx
211     conf.load('compiler_cxx')
212     if is_win32:
213         conf.load('winres')
214     _load_intltool_if_available(conf)
216     # GTK / GIO version check
217     gtk_package_name = 'gtk+-3.0' if conf.options.use_gtk3 else 'gtk+-2.0'
218     minimum_gtk_version = MINIMUM_GTK3_VERSION if conf.options.use_gtk3 else MINIMUM_GTK_VERSION
219     conf.check_cfg(package=gtk_package_name, atleast_version=minimum_gtk_version, uselib_store='GTK',
220         mandatory=True, args='--cflags --libs')
221     conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
222         mandatory=True, args='--cflags --libs')
223     conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
224         mandatory=True, args='--cflags --libs')
225     conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
226     gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
227     conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
228     # remember GTK version for the build step
229     conf.env['gtk_package_name'] = gtk_package_name
230     conf.env['minimum_gtk_version'] = minimum_gtk_version
231     conf.env['use_gtk3'] = conf.options.use_gtk3
233     # Windows specials
234     if is_win32:
235         if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
236             # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
237             new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
238             _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
239             _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
240         _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
241         _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
242         conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
243         # overwrite LOCALEDIR to install message catalogues properly
244         conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
245         # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
246         conf.undefine('DATADIR')
247         conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
248         conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
249         conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
250     else:
251         conf.env['cshlib_PATTERN'] = '%s.so'
252         # DATADIR and LOCALEDIR are defined by the intltool tool
253         # but they are not added to the environment, so we need to
254         _add_define_to_env(conf, 'DATADIR')
255         _add_define_to_env(conf, 'LOCALEDIR')
256         docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
257         libdir = os.path.join(conf.env['PREFIX'], 'lib')
258         mandir = os.path.join(conf.env['DATADIR'], 'man')
259         _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
260         _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
261         _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
263     revision = _get_git_rev(conf)
265     conf.define('ENABLE_NLS', 1)
266     conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
267     conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
268     conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
269     conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
270     conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
271     conf.define('PACKAGE', APPNAME, quote=True)
272     conf.define('VERSION', VERSION, quote=True)
273     conf.define('REVISION', revision or '-1', quote=True)
275     conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
277     # no VTE on Windows
278     if is_win32:
279         conf.options.no_vte = True
281     _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
282     _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
283     _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
285     conf.write_config_header('config.h', remove=False)
287     # some more compiler flags
288     conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
289     if revision is not None:
290         conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
291     # Scintilla flags
292     conf.env.append_value('CFLAGS', ['-DGTK'])
293     conf.env.append_value('CXXFLAGS',
294         ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
296     # summary
297     Logs.pprint('BLUE', 'Summary:')
298     conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
299     conf.msg('Using GTK version', gtk_version)
300     conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
301     conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
302     if revision is not None:
303         conf.msg('Compiling Git revision', revision)
306 def options(opt):
307     # Disable MSVC detection on win32: building Geany with MSVC is currently not supported
308     # If anyone wants to add support for building with MSVC, this hack should be removed.
309     c_compiler['win32'] = ['gcc']
310     cxx_compiler['win32'] = ['g++']
312     opt.load('compiler_cc')
313     opt.load('compiler_cxx')
314     opt.load('intltool')
316     # Features
317     opt.add_option('--disable-plugins', action='store_true', default=False,
318         help='compile without plugin support [default: No]', dest='no_plugins')
319     opt.add_option('--disable-socket', action='store_true', default=False,
320         help='compile without support to detect a running instance [[default: No]',
321         dest='no_socket')
322     opt.add_option('--disable-vte', action='store_true', default=False,
323         help='compile without support for an embedded virtual terminal [[default: No]',
324         dest='no_vte')
325     opt.add_option('--enable-gtk3', action='store_true', default=False,
326         help='compile with GTK3 support (experimental) [[default: No]',
327         dest='use_gtk3')
328     # Paths
329     opt.add_option('--mandir', type='string', default='',
330         help='man documentation', dest='mandir')
331     opt.add_option('--docdir', type='string', default='',
332         help='documentation root', dest='docdir')
333     opt.add_option('--libdir', type='string', default='',
334         help='object code libraries', dest='libdir')
335     # Actions
336     opt.add_option('--hackingdoc', action='store_true', default=False,
337         help='generate HTML documentation from HACKING file', dest='hackingdoc')
340 def build(bld):
341     is_win32 = _target_is_win32(bld)
343     if bld.cmd == 'clean':
344         _remove_linguas_file()
345     if bld.cmd in ('install', 'uninstall'):
346         bld.add_post_fun(_post_install)
348     def build_plugin(plugin_name, install=True):
349         if install:
350             instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
351         else:
352             instpath = None
354         bld(
355             features                = ['c', 'cshlib'],
356             source                  = 'plugins/%s.c' % plugin_name,
357             includes                = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
358             defines                 = 'G_LOG_DOMAIN="%s"' % plugin_name,
359             target                  = plugin_name,
360             uselib                  = ['GTK', 'GLIB', 'GMODULE'],
361             install_path            = instpath)
363     # CTags
364     bld(
365         features        = ['c', 'cstlib'],
366         source          = ctags_sources,
367         name            = 'ctags',
368         target          = 'ctags',
369         includes        = ['.', 'tagmanager', 'tagmanager/ctags'],
370         defines         = 'G_LOG_DOMAIN="CTags"',
371         uselib          = ['GLIB'],
372         install_path    = None)  # do not install this library
374     # Tagmanager
375     bld(
376         features        = ['c', 'cstlib'],
377         source          = tagmanager_sources,
378         name            = 'tagmanager',
379         target          = 'tagmanager',
380         includes        = ['.', 'tagmanager', 'tagmanager/ctags'],
381         defines         = 'G_LOG_DOMAIN="Tagmanager"',
382         uselib          = ['GTK', 'GLIB'],
383         install_path    = None)  # do not install this library
385     # MIO
386     bld(
387         features        = ['c', 'cstlib'],
388         source          = mio_sources,
389         name            = 'mio',
390         target          = 'mio',
391         includes        = ['.', 'tagmanager/mio/'],
392         defines         = 'G_LOG_DOMAIN="MIO"',
393         uselib          = ['GTK', 'GLIB'],
394         install_path    = None)  # do not install this library
396     # Scintilla
397     files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
398     scintilla_sources.update(files)
399     bld(
400         features        = ['c', 'cxx', 'cxxstlib'],
401         name            = 'scintilla',
402         target          = 'scintilla',
403         source          = scintilla_sources,
404         includes        = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
405         uselib          = ['GTK', 'GLIB', 'GMODULE'],
406         install_path    = None)  # do not install this library
408     # Geany
409     if bld.env['HAVE_VTE'] == 1:
410         geany_sources.add('src/vte.c')
411     if is_win32:
412         geany_sources.add('src/win32.c')
413         geany_sources.add('geany_private.rc')
415     bld(
416         features        = ['c', 'cxx', 'cprogram'],
417         name            = 'geany',
418         target          = 'geany',
419         source          = geany_sources,
420         includes        = ['.', 'scintilla/include', 'tagmanager/src'],
421         defines         = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
422         uselib          = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
423         use             = ['scintilla', 'ctags', 'tagmanager', 'mio'])
425     # geanyfunctions.h
426     bld(
427         source  = ['plugins/genapi.py', 'src/plugins.c'],
428         name    = 'geanyfunctions.h',
429         before  = ['c', 'cxx'],
430         cwd     = '%s/plugins' % bld.path.abspath(),
431         rule    = '%s genapi.py -q' % sys.executable)
433     # Plugins
434     if bld.env['HAVE_PLUGINS'] == 1:
435         build_plugin('classbuilder')
436         build_plugin('demoplugin', False)
437         build_plugin('export')
438         build_plugin('filebrowser')
439         build_plugin('htmlchars')
440         build_plugin('saveactions')
441         build_plugin('splitwindow')
443     # Translations
444     if bld.env['INTLTOOL']:
445         bld(
446             features        = ['linguas', 'intltool_po'],
447             podir           = 'po',
448             install_path    = '${LOCALEDIR}',
449             appname         = 'geany')
451     # geany.pc
452     bld(
453         source          = 'geany.pc.in',
454         dct             = {'VERSION': VERSION,
455                            'DEPENDENCIES': '%s >= %s glib-2.0 >= %s' % \
456                                 (bld.env['gtk_package_name'],
457                                  bld.env['minimum_gtk_version'],
458                                  MINIMUM_GLIB_VERSION),
459                            'prefix': bld.env['PREFIX'],
460                            'exec_prefix': '${prefix}',
461                            'libdir': '${exec_prefix}/lib',
462                            'includedir': '${prefix}/include',
463                            'datarootdir': '${prefix}/share',
464                            'datadir': '${datarootdir}',
465                            'localedir': '${datarootdir}/locale'})
467     if not is_win32:
468         # geany.desktop
469         if bld.env['INTLTOOL']:
470             bld(
471                 features        = 'intltool_in',
472                 source          = 'geany.desktop.in',
473                 flags           = ['-d', '-q', '-u', '-c'],
474                 install_path    = '${DATADIR}/applications')
476         # geany.1
477         bld(
478             features        = 'subst',
479             source          = 'doc/geany.1.in',
480             target          = 'geany.1',
481             dct             = {'VERSION': VERSION,
482                                 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
483             install_path    = '${MANDIR}/man1')
485         # geany.spec
486         bld(
487             features        = 'subst',
488             source          = 'geany.spec.in',
489             target          = 'geany.spec',
490             install_path    = None,
491             dct             = {'VERSION': VERSION})
493         # Doxyfile
494         bld(
495             features        = 'subst',
496             source          = 'doc/Doxyfile.in',
497             target          = 'doc/Doxyfile',
498             install_path    = None,
499             dct             = {'VERSION': VERSION})
501     ###
502     # Install files
503     ###
504     if not is_win32:
505         # Headers
506         bld.install_files('${PREFIX}/include/geany', '''
507             src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
508             src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
509             src/prefs.h src/project.h src/search.h src/stash.h src/support.h
510             src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h src/gtkcompat.h
511             plugins/geanyplugin.h plugins/geanyfunctions.h''')
512         bld.install_files('${PREFIX}/include/geany/scintilla', '''
513             scintilla/include/SciLexer.h scintilla/include/Scintilla.h
514             scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
515         bld.install_files('${PREFIX}/include/geany/tagmanager', '''
516             tagmanager/src/tm_file_entry.h tagmanager/src/tm_project.h
517             tagmanager/src/tm_source_file.h tagmanager/src/tm_parser.h
518             tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
519             tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.h
520             tagmanager/src/tm_workspace.h ''')
521     # Docs
522     base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
523     ext = '.txt' if is_win32 else ''
524     html_dir = '' if is_win32 else 'html/'
525     html_name = 'Manual.html' if is_win32 else 'index.html'
526     for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
527         basename = _uc_first(filename, bld)
528         destination_filename = '%s%s' % (basename, ext)
529         destination = os.path.join(base_dir, destination_filename)
530         bld.install_as(destination, filename)
532     start_dir = bld.path.find_dir('doc/images')
533     bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
534     bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
535     bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
536     bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
537     if is_win32:
538         bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
539         bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
540     # Data
541     data_dir = '' if is_win32 else 'geany'
542     start_dir = bld.path.find_dir('data')
543     bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
544     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
545     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
546     bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
547     bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
548     bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
549     if bld.env['use_gtk3']:
550         bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.css')
551     else:
552         bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
554     start_dir = bld.path.find_dir('data/colorschemes')
555     template_dest = '${DATADIR}/%s/colorschemes' % data_dir
556     bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
557     start_dir = bld.path.find_dir('data/templates')
558     template_dest = '${DATADIR}/%s/templates' % data_dir
559     bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
560     # Icons
561     for dest, srcs in geany_icons.items():
562         dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
563         bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
564     # install theme indexes on Windows
565     if is_win32:
566         for dest, srcs in geany_icons_indexes.items():
567             bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
570 def distclean(ctx):
571     Scripting.distclean(ctx)
572     _remove_linguas_file()
575 def _remove_linguas_file():
576     # remove LINGUAS file as well
577     try:
578         os.unlink(LINGUAS_FILE)
579     except OSError:
580         pass
583 @feature('linguas')
584 @before_method('apply_intltool_po')
585 def write_linguas_file(self):
586     if os.path.exists(LINGUAS_FILE):
587         return
588     linguas = ''
589     if 'LINGUAS' in self.env:
590         files = self.env['LINGUAS']
591         for po_filename in files.split(' '):
592             if os.path.exists('po/%s.po' % po_filename):
593                 linguas += '%s ' % po_filename
594     else:
595         files = os.listdir('%s/po' % self.path.abspath())
596         files.sort()
597         for filename in files:
598             if filename.endswith('.po'):
599                 linguas += '%s ' % filename[:-3]
600     file_h = open(LINGUAS_FILE, 'w')
601     file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
602     file_h.close()
605 def _post_install(ctx):
606     is_win32 = _target_is_win32(ctx)
607     if is_win32:
608         return
609     for d in 'hicolor', 'Tango':
610         theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
611         icon_cache_updated = False
612         if not ctx.options.destdir:
613             ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
614             Logs.pprint('GREEN', 'GTK icon cache updated.')
615             icon_cache_updated = True
616         if not icon_cache_updated:
617             Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
618             Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
621 def updatepo(ctx):
622     """update the message catalogs for internationalization"""
623     potfile = '%s.pot' % APPNAME
624     os.chdir('%s/po' % top)
625     try:
626         try:
627             old_size = os.stat(potfile).st_size
628         except OSError:
629             old_size = 0
630         ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
631         size_new = os.stat(potfile).st_size
632         if size_new != old_size:
633             Logs.pprint('CYAN', 'Updated POT file.')
634             Logs.pprint('CYAN', 'Updating translations')
635             ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
636             if ret != 0:
637                 Logs.pprint('RED', 'Updating translations failed')
638         else:
639             Logs.pprint('CYAN', 'POT file is up to date.')
640     except OSError:
641         Logs.pprint('RED', 'Failed to generate pot file.')
644 def apidoc(ctx):
645     """generate API reference documentation"""
646     basedir = ctx.path.abspath()
647     doxygen = _find_program(ctx, 'doxygen')
648     doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
649     os.chdir('doc')
650     Logs.pprint('CYAN', 'Generating API documentation')
651     ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
652     if ret != 0:
653         raise WafError('Generating API documentation failed')
654     # update hacking.html
655     cmd = _find_rst2html(ctx)
656     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
657     os.chdir('..')
660 def htmldoc(ctx):
661     """generate HTML documentation"""
662     # first try rst2html.py as it is the upstream default, fall back to rst2html
663     cmd = _find_rst2html(ctx)
664     os.chdir('doc')
665     Logs.pprint('CYAN', 'Generating HTML documentation')
666     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
667     os.chdir('..')
670 def _find_program(ctx, cmd, **kw):
671     def noop(*args):
672         pass
674     ctx = ConfigurationContext()
675     ctx.to_log = noop
676     ctx.msg = noop
677     return ctx.find_program(cmd, **kw)
680 def _find_rst2html(ctx):
681     cmds = ['rst2html.py', 'rst2html']
682     for command in cmds:
683         cmd = _find_program(ctx, command, mandatory=False)
684         if cmd:
685             break
686     if not cmd:
687         raise WafError(
688             'rst2html.py could not be found. Please install the Python docutils package.')
689     return cmd
692 def _add_define_to_env(conf, key):
693     value = conf.get_define(key)
694     # strip quotes
695     value = value.replace('"', '')
696     conf.env[key] = value
699 def _add_to_env_and_define(conf, key, value, quote=False):
700     conf.define(key, value, quote)
701     conf.env[key] = value
704 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
705     value = default_value
706     if opt_value:
707         if isinstance(opt_value, bool):
708             opt_value = 1
709         value = opt_value
711     if value is not None:
712         _add_to_env_and_define(conf, define_name, value, quote)
713     else:
714         conf.undefine(define_name)
717 def _get_git_rev(conf):
718     if not os.path.isdir('.git'):
719         return
721     try:
722         cmd = 'git rev-parse --short --revs-only HEAD'
723         revision = conf.cmd_and_log(cmd).strip()
724     except WafError:
725         return None
726     else:
727         return revision
730 def _load_intltool_if_available(conf):
731     try:
732         conf.load('intltool')
733         if 'LINGUAS' in os.environ:
734             conf.env['LINGUAS'] = os.environ['LINGUAS']
735     except WafError:
736         # on Windows, we don't hard depend on intltool, on all other platforms raise an error
737         if not _target_is_win32(conf):
738             raise
741 def _target_is_win32(ctx):
742     if 'is_win32' in ctx.env:
743         # cached
744         return ctx.env['is_win32']
745     is_win32 = None
746     if sys.platform == 'win32':
747         is_win32 = True
748     if is_win32 is None:
749         if ctx.env and 'CC' in ctx.env:
750             env_cc = ctx.env['CC']
751             if not isinstance(env_cc, str):
752                 env_cc = ''.join(env_cc)
753             is_win32 = (env_cc.find('mingw') != -1)
754     if is_win32 is None:
755         is_win32 = False
756     # cache for future checks
757     ctx.env['is_win32'] = is_win32
758     return is_win32
761 def _uc_first(string, ctx):
762     if _target_is_win32(ctx):
763         return string.title()
764     return string