Re-add the previous workaround to remember the directory Geany was started from
[geany-mirror.git] / wscript
blob410280f3542503874647d119055d175acf4b4e26
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', '%s/lib' % 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', [
249             '-mwindows',
250             '-static-libgcc',
251             '-static-libstdc++'])
252         conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
253     else:
254         conf.env['cshlib_PATTERN'] = '%s.so'
255         # DATADIR and LOCALEDIR are defined by the intltool tool
256         # but they are not added to the environment, so we need to
257         _add_define_to_env(conf, 'DATADIR')
258         _add_define_to_env(conf, 'LOCALEDIR')
259         docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
260         libdir = os.path.join(conf.env['PREFIX'], 'lib')
261         mandir = os.path.join(conf.env['DATADIR'], 'man')
262         _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
263         _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
264         _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
266     revision = _get_git_rev(conf)
268     conf.define('ENABLE_NLS', 1)
269     conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
270     conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
271     conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
272     conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
273     conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
274     conf.define('PACKAGE', APPNAME, quote=True)
275     conf.define('VERSION', VERSION, quote=True)
276     conf.define('REVISION', revision or '-1', quote=True)
278     conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
280     # no VTE on Windows
281     if is_win32:
282         conf.options.no_vte = True
284     _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
285     _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
286     _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
288     conf.write_config_header('config.h', remove=False)
290     # some more compiler flags
291     conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
292     if revision is not None:
293         conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
294     # Scintilla flags
295     conf.env.append_value('CFLAGS', ['-DGTK'])
296     conf.env.append_value('CXXFLAGS',
297         ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
299     # summary
300     Logs.pprint('BLUE', 'Summary:')
301     conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
302     conf.msg('Using GTK version', gtk_version)
303     conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
304     conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
305     if revision is not None:
306         conf.msg('Compiling Git revision', revision)
309 def options(opt):
310     # Disable MSVC detection on win32: building Geany with MSVC is currently not supported
311     # If anyone wants to add support for building with MSVC, this hack should be removed.
312     c_compiler['win32'] = ['gcc']
313     cxx_compiler['win32'] = ['g++']
315     opt.load('compiler_cc')
316     opt.load('compiler_cxx')
317     opt.load('intltool')
319     # Option
320     opt.add_option('--no-scm', action='store_true', default=False,
321         help='Disable SCM detection [default: No]', dest='no_scm')
322     # Features
323     opt.add_option('--disable-plugins', action='store_true', default=False,
324         help='compile without plugin support [default: No]', dest='no_plugins')
325     opt.add_option('--disable-socket', action='store_true', default=False,
326         help='compile without support to detect a running instance [[default: No]',
327         dest='no_socket')
328     opt.add_option('--disable-vte', action='store_true', default=False,
329         help='compile without support for an embedded virtual terminal [[default: No]',
330         dest='no_vte')
331     opt.add_option('--enable-gtk3', action='store_true', default=False,
332         help='compile with GTK3 support (experimental) [[default: No]',
333         dest='use_gtk3')
334     # Paths
335     opt.add_option('--mandir', type='string', default='',
336         help='man documentation', dest='mandir')
337     opt.add_option('--docdir', type='string', default='',
338         help='documentation root', dest='docdir')
339     opt.add_option('--libdir', type='string', default='',
340         help='object code libraries', dest='libdir')
341     # Actions
342     opt.add_option('--hackingdoc', action='store_true', default=False,
343         help='generate HTML documentation from HACKING file', dest='hackingdoc')
346 def build(bld):
347     is_win32 = _target_is_win32(bld)
349     if bld.cmd == 'clean':
350         _remove_linguas_file()
351     if bld.cmd in ('install', 'uninstall'):
352         bld.add_post_fun(_post_install)
354     def build_plugin(plugin_name, install=True):
355         if install:
356             instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
357         else:
358             instpath = None
360         bld(
361             features                = ['c', 'cshlib'],
362             source                  = 'plugins/%s.c' % plugin_name,
363             includes                = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
364             defines                 = 'G_LOG_DOMAIN="%s"' % plugin_name,
365             target                  = plugin_name,
366             uselib                  = ['GTK', 'GLIB', 'GMODULE'],
367             install_path            = instpath)
369     # CTags
370     bld(
371         features        = ['c', 'cstlib'],
372         source          = ctags_sources,
373         name            = 'ctags',
374         target          = 'ctags',
375         includes        = ['.', 'tagmanager', 'tagmanager/ctags'],
376         defines         = 'G_LOG_DOMAIN="CTags"',
377         uselib          = ['GLIB'],
378         install_path    = None)  # do not install this library
380     # Tagmanager
381     bld(
382         features        = ['c', 'cstlib'],
383         source          = tagmanager_sources,
384         name            = 'tagmanager',
385         target          = 'tagmanager',
386         includes        = ['.', 'tagmanager', 'tagmanager/ctags'],
387         defines         = 'G_LOG_DOMAIN="Tagmanager"',
388         uselib          = ['GTK', 'GLIB'],
389         install_path    = None)  # do not install this library
391     # MIO
392     bld(
393         features        = ['c', 'cstlib'],
394         source          = mio_sources,
395         name            = 'mio',
396         target          = 'mio',
397         includes        = ['.', 'tagmanager/mio/'],
398         defines         = 'G_LOG_DOMAIN="MIO"',
399         uselib          = ['GTK', 'GLIB'],
400         install_path    = None)  # do not install this library
402     # Scintilla
403     files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
404     scintilla_sources.update(files)
405     bld(
406         features        = ['c', 'cxx', 'cxxstlib'],
407         name            = 'scintilla',
408         target          = 'scintilla',
409         source          = scintilla_sources,
410         includes        = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
411         uselib          = ['GTK', 'GLIB', 'GMODULE'],
412         install_path    = None)  # do not install this library
414     # Geany
415     if bld.env['HAVE_VTE'] == 1:
416         geany_sources.add('src/vte.c')
417     if is_win32:
418         geany_sources.add('src/win32.c')
419         geany_sources.add('geany_private.rc')
421     bld(
422         features        = ['c', 'cxx', 'cprogram'],
423         name            = 'geany',
424         target          = 'geany',
425         source          = geany_sources,
426         includes        = ['.', 'scintilla/include', 'tagmanager/src'],
427         defines         = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
428         uselib          = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
429         use             = ['scintilla', 'ctags', 'tagmanager', 'mio'])
431     # geanyfunctions.h
432     bld(
433         source  = ['plugins/genapi.py', 'src/plugins.c'],
434         name    = 'geanyfunctions.h',
435         before  = ['c', 'cxx'],
436         cwd     = '%s/plugins' % bld.path.abspath(),
437         rule    = '%s genapi.py -q' % sys.executable)
439     # Plugins
440     if bld.env['HAVE_PLUGINS'] == 1:
441         build_plugin('classbuilder')
442         build_plugin('demoplugin', False)
443         build_plugin('export')
444         build_plugin('filebrowser')
445         build_plugin('htmlchars')
446         build_plugin('saveactions')
447         build_plugin('splitwindow')
449     # Translations
450     if bld.env['INTLTOOL']:
451         bld(
452             features        = ['linguas', 'intltool_po'],
453             podir           = 'po',
454             install_path    = '${LOCALEDIR}',
455             appname         = 'geany')
457     # geany.pc
458     bld(
459         source          = 'geany.pc.in',
460         dct             = {'VERSION': VERSION,
461                            'DEPENDENCIES': '%s >= %s glib-2.0 >= %s' % \
462                                 (bld.env['gtk_package_name'],
463                                  bld.env['minimum_gtk_version'],
464                                  MINIMUM_GLIB_VERSION),
465                            'prefix': bld.env['PREFIX'],
466                            'exec_prefix': '${prefix}',
467                            'libdir': '${exec_prefix}/lib',
468                            'includedir': '${prefix}/include',
469                            'datarootdir': '${prefix}/share',
470                            'datadir': '${datarootdir}',
471                            'localedir': '${datarootdir}/locale'})
473     if not is_win32:
474         # geany.desktop
475         if bld.env['INTLTOOL']:
476             bld(
477                 features        = 'intltool_in',
478                 source          = 'geany.desktop.in',
479                 flags           = ['-d', '-q', '-u', '-c'],
480                 install_path    = '${DATADIR}/applications')
482         # geany.1
483         bld(
484             features        = 'subst',
485             source          = 'doc/geany.1.in',
486             target          = 'geany.1',
487             dct             = {'VERSION': VERSION,
488                                 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
489             install_path    = '${MANDIR}/man1')
491         # geany.spec
492         bld(
493             features        = 'subst',
494             source          = 'geany.spec.in',
495             target          = 'geany.spec',
496             install_path    = None,
497             dct             = {'VERSION': VERSION})
499         # Doxyfile
500         bld(
501             features        = 'subst',
502             source          = 'doc/Doxyfile.in',
503             target          = 'doc/Doxyfile',
504             install_path    = None,
505             dct             = {'VERSION': VERSION})
507     ###
508     # Install files
509     ###
510     # Headers
511     bld.install_files('${PREFIX}/include/geany', '''
512         src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
513         src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
514         src/prefs.h src/project.h src/search.h src/stash.h src/support.h
515         src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h src/gtkcompat.h
516         plugins/geanyplugin.h plugins/geanyfunctions.h''')
517     bld.install_files('${PREFIX}/include/geany/scintilla', '''
518         scintilla/include/SciLexer.h scintilla/include/Scintilla.h
519         scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
520     bld.install_files('${PREFIX}/include/geany/tagmanager', '''
521         tagmanager/src/tm_file_entry.h tagmanager/src/tm_project.h
522         tagmanager/src/tm_source_file.h tagmanager/src/tm_parser.h
523         tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
524         tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.h
525         tagmanager/src/tm_workspace.h ''')
526     # Docs
527     base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
528     ext = '.txt' if is_win32 else ''
529     html_dir = '' if is_win32 else 'html/'
530     html_name = 'Manual.html' if is_win32 else 'index.html'
531     for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
532         basename = _uc_first(filename, bld)
533         destination_filename = '%s%s' % (basename, ext)
534         destination = os.path.join(base_dir, destination_filename)
535         bld.install_as(destination, filename)
537     start_dir = bld.path.find_dir('doc/images')
538     bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
539     bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
540     bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
541     bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
542     if is_win32:
543         bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
544         bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
545     # Data
546     data_dir = '' if is_win32 else 'geany'
547     start_dir = bld.path.find_dir('data')
548     bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
549     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
550     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
551     bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
552     bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
553     bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
554     if bld.env['use_gtk3']:
555         bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.css')
556     else:
557         bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
559     start_dir = bld.path.find_dir('data/colorschemes')
560     template_dest = '${DATADIR}/%s/colorschemes' % data_dir
561     bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
562     start_dir = bld.path.find_dir('data/templates')
563     template_dest = '${DATADIR}/%s/templates' % data_dir
564     bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
565     # Icons
566     for dest, srcs in geany_icons.items():
567         dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
568         bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
569     # install theme indexes on Windows
570     if is_win32:
571         for dest, srcs in geany_icons_indexes.items():
572             bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
575 def distclean(ctx):
576     Scripting.distclean(ctx)
577     _remove_linguas_file()
580 def _remove_linguas_file():
581     # remove LINGUAS file as well
582     try:
583         os.unlink(LINGUAS_FILE)
584     except OSError:
585         pass
588 @feature('linguas')
589 @before_method('apply_intltool_po')
590 def write_linguas_file(self):
591     if os.path.exists(LINGUAS_FILE):
592         return
593     linguas = ''
594     if 'LINGUAS' in self.env:
595         files = self.env['LINGUAS']
596         for po_filename in files.split(' '):
597             if os.path.exists('po/%s.po' % po_filename):
598                 linguas += '%s ' % po_filename
599     else:
600         files = os.listdir('%s/po' % self.path.abspath())
601         files.sort()
602         for filename in files:
603             if filename.endswith('.po'):
604                 linguas += '%s ' % filename[:-3]
605     file_h = open(LINGUAS_FILE, 'w')
606     file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
607     file_h.close()
610 def _post_install(ctx):
611     is_win32 = _target_is_win32(ctx)
612     if is_win32:
613         return
614     for d in 'hicolor', 'Tango':
615         theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
616         icon_cache_updated = False
617         if not ctx.options.destdir:
618             ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
619             Logs.pprint('GREEN', 'GTK icon cache updated.')
620             icon_cache_updated = True
621         if not icon_cache_updated:
622             Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
623             Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
626 def updatepo(ctx):
627     """update the message catalogs for internationalization"""
628     potfile = '%s.pot' % APPNAME
629     os.chdir('%s/po' % top)
630     try:
631         try:
632             old_size = os.stat(potfile).st_size
633         except OSError:
634             old_size = 0
635         ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
636         size_new = os.stat(potfile).st_size
637         if size_new != old_size:
638             Logs.pprint('CYAN', 'Updated POT file.')
639             Logs.pprint('CYAN', 'Updating translations')
640             ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
641             if ret != 0:
642                 Logs.pprint('RED', 'Updating translations failed')
643         else:
644             Logs.pprint('CYAN', 'POT file is up to date.')
645     except OSError:
646         Logs.pprint('RED', 'Failed to generate pot file.')
649 def apidoc(ctx):
650     """generate API reference documentation"""
651     basedir = ctx.path.abspath()
652     doxygen = _find_program(ctx, 'doxygen')
653     doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
654     os.chdir('doc')
655     Logs.pprint('CYAN', 'Generating API documentation')
656     ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
657     if ret != 0:
658         raise WafError('Generating API documentation failed')
659     # update hacking.html
660     cmd = _find_rst2html(ctx)
661     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
662     os.chdir('..')
665 def htmldoc(ctx):
666     """generate HTML documentation"""
667     # first try rst2html.py as it is the upstream default, fall back to rst2html
668     cmd = _find_rst2html(ctx)
669     os.chdir('doc')
670     Logs.pprint('CYAN', 'Generating HTML documentation')
671     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
672     os.chdir('..')
675 def _find_program(ctx, cmd, **kw):
676     def noop(*args):
677         pass
679     ctx = ConfigurationContext()
680     ctx.to_log = noop
681     ctx.msg = noop
682     return ctx.find_program(cmd, **kw)
685 def _find_rst2html(ctx):
686     cmds = ['rst2html.py', 'rst2html']
687     for command in cmds:
688         cmd = _find_program(ctx, command, mandatory=False)
689         if cmd:
690             break
691     if not cmd:
692         raise WafError(
693             'rst2html.py could not be found. Please install the Python docutils package.')
694     return cmd
697 def _add_define_to_env(conf, key):
698     value = conf.get_define(key)
699     # strip quotes
700     value = value.replace('"', '')
701     conf.env[key] = value
704 def _add_to_env_and_define(conf, key, value, quote=False):
705     conf.define(key, value, quote)
706     conf.env[key] = value
709 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
710     value = default_value
711     if opt_value:
712         if isinstance(opt_value, bool):
713             opt_value = 1
714         value = opt_value
716     if value is not None:
717         _add_to_env_and_define(conf, define_name, value, quote)
718     else:
719         conf.undefine(define_name)
722 def _get_git_rev(conf):
723     if conf.options.no_scm:
724         return
726     if not os.path.isdir('.git'):
727         return
729     try:
730         cmd = 'git rev-parse --short --revs-only HEAD'
731         revision = conf.cmd_and_log(cmd).strip()
732     except WafError:
733         return None
734     else:
735         return revision
738 def _load_intltool_if_available(conf):
739     try:
740         conf.load('intltool')
741         if 'LINGUAS' in os.environ:
742             conf.env['LINGUAS'] = os.environ['LINGUAS']
743     except WafError:
744         # on Windows, we don't hard depend on intltool, on all other platforms raise an error
745         if not _target_is_win32(conf):
746             raise
749 def _target_is_win32(ctx):
750     if 'is_win32' in ctx.env:
751         # cached
752         return ctx.env['is_win32']
753     is_win32 = None
754     if sys.platform == 'win32':
755         is_win32 = True
756     if is_win32 is None:
757         if ctx.env and 'CC' in ctx.env:
758             env_cc = ctx.env['CC']
759             if not isinstance(env_cc, str):
760                 env_cc = ''.join(env_cc)
761             is_win32 = (env_cc.find('mingw') != -1)
762     if is_win32 is None:
763         is_win32 = False
764     # cache for future checks
765     ctx.env['is_win32'] = is_win32
766     return is_win32
769 def _uc_first(string, ctx):
770     if _target_is_win32(ctx):
771         return string.title()
772     return string