Make editor menu initially hidden
[geany-mirror.git] / wscript
blob1f3211b1bb316a3e70f54993e7c6be064c077388
1 # -*- coding: utf-8 -*-
3 # WAF build script - this file is part of Geany, a fast and lightweight IDE
5 # Copyright 2008-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
6 # Copyright 2008-2011 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 ConfigurationError, WafError
48 from waflib.TaskGen import feature
51 APPNAME = 'geany'
52 VERSION = '1.22'
53 LINGUAS_FILE = 'po/LINGUAS'
55 top = '.'
56 out = '_build_'
59 mio_sources = set(['tagmanager/mio/mio.c'])
61 tagmanager_sources = set([
62     'tagmanager/args.c', 'tagmanager/abc.c', 'tagmanager/actionscript.c', 'tagmanager/asm.c',
63     'tagmanager/basic.c', 'tagmanager/c.c', 'tagmanager/cobol.c',
64     'tagmanager/conf.c', 'tagmanager/css.c', 'tagmanager/ctags.c', 'tagmanager/diff.c',
65     'tagmanager/docbook.c', 'tagmanager/entry.c', 'tagmanager/fortran.c', 'tagmanager/get.c',
66     'tagmanager/haskell.c', 'tagmanager/haxe.c', 'tagmanager/html.c', 'tagmanager/js.c',
67     'tagmanager/keyword.c', 'tagmanager/latex.c', 'tagmanager/lregex.c', 'tagmanager/lua.c',
68     'tagmanager/make.c', 'tagmanager/markdown.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
69     'tagmanager/nestlevel.c', 'tagmanager/objc.c', 'tagmanager/options.c',
70     'tagmanager/parse.c', 'tagmanager/pascal.c', 'tagmanager/r.c',
71     'tagmanager/perl.c', 'tagmanager/php.c', 'tagmanager/python.c', 'tagmanager/read.c',
72     'tagmanager/rest.c', 'tagmanager/ruby.c', 'tagmanager/sh.c', 'tagmanager/sort.c',
73     'tagmanager/sql.c', 'tagmanager/strlist.c', 'tagmanager/txt2tags.c', 'tagmanager/tcl.c',
74     'tagmanager/tm_file_entry.c',
75     'tagmanager/tm_project.c', 'tagmanager/tm_source_file.c', 'tagmanager/tm_symbol.c',
76     'tagmanager/tm_tag.c', 'tagmanager/tm_tagmanager.c', 'tagmanager/tm_work_object.c',
77     'tagmanager/tm_workspace.c', 'tagmanager/vhdl.c', 'tagmanager/verilog.c', 'tagmanager/vstring.c'])
79 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
81 geany_sources = set([
82     'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
83     'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
84     'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
85     'src/highlighting.c', 'src/keybindings.c',
86     'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
87     'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
88     'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
89     'src/symbols.c',
90     'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
91     'src/ui_utils.c', 'src/utils.c'])
95 def configure(conf):
97     conf.check_waf_version(mini='1.6.1')
99     conf.load('compiler_c')
100     is_win32 = _target_is_win32(conf)
102     conf.check_cc(header_name='fcntl.h', mandatory=False)
103     conf.check_cc(header_name='fnmatch.h', mandatory=False)
104     conf.check_cc(header_name='glob.h', mandatory=False)
105     conf.check_cc(header_name='sys/time.h', mandatory=False)
106     conf.check_cc(header_name='sys/types.h', mandatory=False)
107     conf.check_cc(header_name='sys/stat.h', mandatory=False)
108     conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
109     conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
111     if conf.options.gnu_regex:
112         _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
113         _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
114     else:
115         try:
116             conf.check_cc(header_name='regex.h')
117             conf.check_cc(function_name='regcomp', header_name='regex.h')
118         except ConfigurationError:
119             _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
120             _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
122     conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
123     conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
124     conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
125     conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
126     conf.check_cc(function_name='strstr', header_name='string.h')
128     # check sunOS socket support
129     if Options.platform == 'sunos':
130         conf.check_cc(function_name='socket', lib='socket',
131                       header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
133     # check for cxx after the header and function checks have been done to ensure they are
134     # checked with cc not cxx
135     conf.load('compiler_cxx')
136     if is_win32:
137         conf.load('winres')
138     _load_intltool_if_available(conf)
140     # GTK / GIO version check
141     conf.check_cfg(package='gtk+-2.0', atleast_version='2.16.0', uselib_store='GTK',
142         mandatory=True, args='--cflags --libs')
143     conf.check_cfg(package='glib-2.0', atleast_version='2.20.0', uselib_store='GLIB',
144         mandatory=True, args='--cflags --libs')
145     conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
146     gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK') or 'Unknown'
147     conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
149     # Windows specials
150     if is_win32:
151         if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
152             # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
153             new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
154             _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
155             _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
156         _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
157         _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
158         conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
159         # overwrite LOCALEDIR to install message catalogues properly
160         conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
161         # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
162         conf.undefine('DATADIR')
163         conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
164         conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
165         conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
166     else:
167         conf.env['cshlib_PATTERN'] = '%s.so'
168         # DATADIR and LOCALEDIR are defined by the intltool tool
169         # but they are not added to the environment, so we need to
170         _add_define_to_env(conf, 'DATADIR')
171         _add_define_to_env(conf, 'LOCALEDIR')
172         docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
173         libdir = os.path.join(conf.env['PREFIX'], 'lib')
174         mandir = os.path.join(conf.env['DATADIR'], 'man')
175         _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
176         _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
177         _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
179     revision = _get_git_rev(conf)
181     conf.define('ENABLE_NLS', 1)
182     conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
183     conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
184     conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
185     conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
186     conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
187     conf.define('PACKAGE', APPNAME, quote=True)
188     conf.define('VERSION', VERSION, quote=True)
189     conf.define('REVISION', revision or '-1', quote=True)
191     conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
193     # no VTE on Windows
194     if is_win32:
195         conf.options.no_vte = True
197     _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
198     _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
199     _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
201     conf.write_config_header('config.h', remove=False)
203     # some more compiler flags
204     conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
205     if revision is not None:
206         conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
207     # Scintilla flags
208     conf.env.append_value('CFLAGS', ['-DGTK'])
209     conf.env.append_value('CXXFLAGS',
210         ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
212     # summary
213     Logs.pprint('BLUE', 'Summary:')
214     conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
215     conf.msg('Using GTK version', gtk_version)
216     conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
217     conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
218     conf.msg('GNU regex library', conf.env['USE_INCLUDED_REGEX'] and 'built-in' or 'system')
219     if revision is not None:
220         conf.msg('Compiling Git revision', revision)
223 def options(opt):
224     opt.tool_options('compiler_cc')
225     opt.tool_options('compiler_cxx')
226     opt.tool_options('intltool')
228     # Features
229     opt.add_option('--disable-plugins', action='store_true', default=False,
230         help='compile without plugin support [default: No]', dest='no_plugins')
231     opt.add_option('--disable-socket', action='store_true', default=False,
232         help='compile without support to detect a running instance [[default: No]',
233         dest='no_socket')
234     opt.add_option('--disable-vte', action='store_true', default=False,
235         help='compile without support for an embedded virtual terminal [[default: No]',
236         dest='no_vte')
237     opt.add_option('--enable-gnu-regex', action='store_true', default=False,
238         help='compile with included GNU regex library [default: No]', dest='gnu_regex')
239     # Paths
240     opt.add_option('--mandir', type='string', default='',
241         help='man documentation', dest='mandir')
242     opt.add_option('--docdir', type='string', default='',
243         help='documentation root', dest='docdir')
244     opt.add_option('--libdir', type='string', default='',
245         help='object code libraries', dest='libdir')
246     # Actions
247     opt.add_option('--hackingdoc', action='store_true', default=False,
248         help='generate HTML documentation from HACKING file', dest='hackingdoc')
251 def build(bld):
252     is_win32 = _target_is_win32(bld)
254     if bld.cmd == 'clean':
255         _remove_linguas_file()
256     if bld.cmd in ('install', 'uninstall'):
257         bld.add_post_fun(_post_install)
259     def build_plugin(plugin_name, install=True):
260         if install:
261             instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
262         else:
263             instpath = None
265         bld.new_task_gen(
266             features                = ['c', 'cshlib'],
267             source                  = 'plugins/%s.c' % plugin_name,
268             includes                = ['.', 'src/', 'scintilla/include', 'tagmanager/include'],
269             defines                 = 'G_LOG_DOMAIN="%s"' % plugin_name,
270             target                  = plugin_name,
271             uselib                  = ['GTK', 'GLIB'],
272             install_path            = instpath)
275     # Tagmanager
276     if bld.env['USE_INCLUDED_REGEX'] == 1:
277         tagmanager_sources.add('tagmanager/regex.c')
278     bld.new_task_gen(
279         features        = ['c', 'cstlib'],
280         source          = tagmanager_sources,
281         name            = 'tagmanager',
282         target          = 'tagmanager',
283         includes        = ['.', 'tagmanager', 'tagmanager/include'],
284         defines         = 'G_LOG_DOMAIN="Tagmanager"',
285         uselib          = ['GTK', 'GLIB'],
286         install_path    = None) # do not install this library
289     # MIO
290     bld.new_task_gen(
291         features        = ['c', 'cstlib'],
292         source          = mio_sources,
293         name            = 'mio',
294         target          = 'mio',
295         includes        = ['.', 'tagmanager/mio/'],
296         defines         = 'G_LOG_DOMAIN="MIO"',
297         uselib          = ['GTK', 'GLIB'],
298         install_path    = None) # do not install this library
301     # Scintilla
302     files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
303     scintilla_sources.update(files)
304     bld.new_task_gen(
305         features        = ['c', 'cxx', 'cxxstlib'],
306         name            = 'scintilla',
307         target          = 'scintilla',
308         source          = scintilla_sources,
309         includes        = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
310         uselib          = 'GTK',
311         install_path    = None) # do not install this library
314     # Geany
315     if bld.env['HAVE_VTE'] == 1:
316         geany_sources.add('src/vte.c')
317     if is_win32:
318         geany_sources.add('src/win32.c')
319         geany_sources.add('geany_private.rc')
321     bld.new_task_gen(
322         features        = ['c', 'cxx', 'cprogram'],
323         name            = 'geany',
324         target          = 'geany',
325         source          = geany_sources,
326         includes        = ['.', 'scintilla/include/', 'tagmanager/include/'],
327         defines         = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
328         linkflags       = ['-Wl,--export-dynamic'],
329         uselib          = ['GTK', 'GLIB', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
330         use             = ['scintilla', 'tagmanager', 'mio'])
332     # geanyfunctions.h
333     bld.new_task_gen(
334         source  = ['plugins/genapi.py', 'src/plugins.c'],
335         name    = 'geanyfunctions.h',
336         before  = ['c', 'cxx'],
337         cwd     = '%s/plugins' % bld.path.abspath(),
338         rule    = 'python genapi.py -q')
340     # Plugins
341     if bld.env['HAVE_PLUGINS'] == 1:
342         build_plugin('classbuilder')
343         build_plugin('demoplugin', False)
344         build_plugin('export')
345         build_plugin('filebrowser')
346         build_plugin('htmlchars')
347         build_plugin('saveactions')
348         build_plugin('splitwindow')
350     # Translations
351     if bld.env['INTLTOOL']:
352         bld.new_task_gen(
353             features        = ['linguas', 'intltool_po'],
354             podir           = 'po',
355             install_path    = '${LOCALEDIR}',
356             appname         = 'geany')
358     # geany.pc
359     bld.new_task_gen(
360         source          = 'geany.pc.in',
361         dct             = {'VERSION' : VERSION,
362                            'prefix': bld.env['PREFIX'],
363                            'exec_prefix': '${prefix}',
364                            'libdir': '${exec_prefix}/lib',
365                            'includedir': '${prefix}/include',
366                            'datarootdir': '${prefix}/share',
367                            'datadir': '${datarootdir}',
368                            'localedir': '${datarootdir}/locale'})
370     if not is_win32:
371         # geany.desktop
372         if bld.env['INTLTOOL']:
373             bld.new_task_gen(
374                 features        = 'intltool_in',
375                 source          = 'geany.desktop.in',
376                 flags           = [ '-d', '-q', '-u', '-c' ],
377                 install_path    = '${DATADIR}/applications')
379         # geany.1
380         bld.new_task_gen(
381             features        = 'subst',
382             source          = 'doc/geany.1.in',
383             target          = 'geany.1',
384             dct             = {'VERSION' : VERSION,
385                                 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
386             install_path    = '${MANDIR}/man1')
388         # geany.spec
389         bld.new_task_gen(
390             features        = 'subst',
391             source          = 'geany.spec.in',
392             target          = 'geany.spec',
393             install_path    = None,
394             dct             = {'VERSION' : VERSION})
396         # Doxyfile
397         bld.new_task_gen(
398             features        = 'subst',
399             source          = 'doc/Doxyfile.in',
400             target          = 'doc/Doxyfile',
401             install_path    = None,
402             dct             = {'VERSION' : VERSION})
404     ###
405     # Install files
406     ###
407     if not is_win32:
408         # Headers
409         bld.install_files('${PREFIX}/include/geany', '''
410             src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
411             src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
412             src/prefs.h src/project.h src/search.h src/stash.h src/support.h
413             src/templates.h src/toolbar.h src/ui_utils.h src/utils.h
414             plugins/geanyplugin.h plugins/geanyfunctions.h''')
415         bld.install_files('${PREFIX}/include/geany/scintilla', '''
416             scintilla/include/SciLexer.h scintilla/include/Scintilla.h
417             scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
418         bld.install_files('${PREFIX}/include/geany/tagmanager', '''
419             tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
420             tagmanager/include/tm_source_file.h
421             tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
422             tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
423             tagmanager/include/tm_workspace.h ''')
424     # Docs
425     base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
426     ext = '.txt' if is_win32 else ''
427     html_dir = '' if is_win32 else 'html/'
428     html_name = 'Manual.html' if is_win32 else 'index.html'
429     for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
430         basename = _uc_first(filename, bld)
431         destination_filename = '%s%s' % (basename, ext)
432         destination = os.path.join(base_dir, destination_filename)
433         bld.install_as(destination, filename)
435     start_dir = bld.path.find_dir('doc/images')
436     bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
437     bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
438     bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
439     bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
440     if is_win32:
441         bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
442         bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
443     # Data
444     data_dir = '' if is_win32 else 'geany'
445     start_dir = bld.path.find_dir('data')
446     bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
447     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
448     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
449     bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
450     bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
451     bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
452     start_dir = bld.path.find_dir('data/colorschemes')
453     template_dest = '${DATADIR}/%s/colorschemes' % data_dir
454     bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
455     start_dir = bld.path.find_dir('data/templates')
456     template_dest = '${DATADIR}/%s/templates' % data_dir
457     bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
458     # Icons
459     icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
460     start_dir = bld.path.find_dir('icons/16x16')
461     bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
462     if not is_win32:
463         start_dir = bld.path.find_dir('icons/48x48')
464         icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
465         bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
466         start_dir = bld.path.find_dir('icons/scalable')
467         scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
468         bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
471 def distclean(ctx):
472     Scripting.distclean(ctx)
473     _remove_linguas_file()
476 def _remove_linguas_file():
477     # remove LINGUAS file as well
478     try:
479         os.unlink(LINGUAS_FILE)
480     except OSError:
481         pass
484 @feature('linguas')
485 def write_linguas_file(self):
486     if os.path.exists(LINGUAS_FILE):
487         return
488     linguas = ''
489     if 'LINGUAS' in self.env:
490         files = self.env['LINGUAS']
491         for po_filename in files.split(' '):
492             if os.path.exists ('po/%s.po' % po_filename):
493                 linguas += '%s ' % po_filename
494     else:
495         files = os.listdir('%s/po' % self.path.abspath())
496         files.sort()
497         for filename in files:
498             if filename.endswith('.po'):
499                 linguas += '%s ' % filename[:-3]
500     file_h = open(LINGUAS_FILE, 'w')
501     file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
502     file_h.close()
505 def _post_install(ctx):
506     is_win32 = _target_is_win32(ctx)
507     if is_win32:
508         return
509     theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
510     icon_cache_updated = False
511     if not ctx.options.destdir:
512         ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
513         Logs.pprint('GREEN', 'GTK icon cache updated.')
514         icon_cache_updated = True
515     if not icon_cache_updated:
516         Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
517         Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
520 def updatepo(ctx):
521     """update the message catalogs for internationalization"""
522     potfile = '%s.pot' % APPNAME
523     os.chdir('%s/po' % top)
524     try:
525         try:
526             old_size = os.stat(potfile).st_size
527         except OSError:
528             old_size = 0
529         ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
530         size_new = os.stat(potfile).st_size
531         if size_new != old_size:
532             Logs.pprint('CYAN', 'Updated POT file.')
533             Logs.pprint('CYAN', 'Updating translations')
534             ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
535             if ret != 0:
536                 Logs.pprint('RED', 'Updating translations failed')
537         else:
538             Logs.pprint('CYAN', 'POT file is up to date.')
539     except OSError:
540         Logs.pprint('RED', 'Failed to generate pot file.')
543 def apidoc(ctx):
544     """generate API reference documentation"""
545     basedir = ctx.path.abspath()
546     doxygen = _find_program(ctx, 'doxygen')
547     doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
548     os.chdir('doc')
549     Logs.pprint('CYAN', 'Generating API documentation')
550     ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
551     if ret != 0:
552         raise WafError('Generating API documentation failed')
553     # update hacking.html
554     cmd = _find_rst2html(ctx)
555     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
556     os.chdir('..')
559 def htmldoc(ctx):
560     """generate HTML documentation"""
561     # first try rst2html.py as it is the upstream default, fall back to rst2html
562     cmd = _find_rst2html(ctx)
563     os.chdir('doc')
564     Logs.pprint('CYAN', 'Generating HTML documentation')
565     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
566     os.chdir('..')
569 def _find_program(ctx, cmd, **kw):
570     def noop(*args):
571         pass
573     ctx = ConfigurationContext()
574     ctx.to_log = noop
575     ctx.msg = noop
576     return ctx.find_program(cmd, **kw)
579 def _find_rst2html(ctx):
580     cmds = ['rst2html.py', 'rst2html']
581     for command in cmds:
582         cmd = _find_program(ctx, command, mandatory=False)
583         if cmd:
584             break
585     if not cmd:
586         raise WafError(
587             'rst2html.py could not be found. Please install the Python docutils package.')
588     return cmd
591 def _add_define_to_env(conf, key):
592     value = conf.get_define(key)
593     # strip quotes
594     value = value.replace('"', '')
595     conf.env[key] = value
598 def _add_to_env_and_define(conf, key, value, quote=False):
599     conf.define(key, value, quote)
600     conf.env[key] = value
603 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
604     value = default_value
605     if opt_value:
606         if isinstance(opt_value, bool):
607             opt_value = 1
608         value = opt_value
610     if value is not None:
611         _add_to_env_and_define(conf, define_name, value, quote)
612     else:
613         conf.undefine(define_name)
616 def _get_git_rev(conf):
617     if not os.path.isdir('.git'):
618         return
620     try:
621         cmd = 'git rev-parse --short --revs-only HEAD'
622         revision = conf.cmd_and_log(cmd).strip()
623     except WafError:
624         return None
625     else:
626         return revision
629 def _load_intltool_if_available(conf):
630     try:
631         conf.check_tool('intltool')
632         if 'LINGUAS' in os.environ:
633             conf.env['LINGUAS'] = os.environ['LINGUAS']
634     except WafError:
635         # on Windows, we don't hard depend on intltool, on all other platforms raise an error
636         if not _target_is_win32(conf):
637             raise
640 def _target_is_win32(ctx):
641     if 'is_win32' in ctx.env:
642         # cached
643         return ctx.env['is_win32']
644     is_win32 = None
645     if sys.platform == 'win32':
646         is_win32 = True
647     if is_win32 is None:
648         if ctx.env and 'CC' in ctx.env:
649             env_cc = ctx.env['CC']
650             if not isinstance(env_cc, str):
651                 env_cc = ''.join(env_cc)
652             is_win32 = (env_cc.find('mingw') != -1)
653     if is_win32 is None:
654         is_win32 = False
655     # cache for future checks
656     ctx.env['is_win32'] = is_win32
657     return is_win32
660 def _uc_first(string, ctx):
661     if _target_is_win32(ctx):
662         return string.title()
663     return string