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.
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)
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).
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
53 LINGUAS_FILE = 'po/LINGUAS'
54 MINIMUM_GTK_VERSION = '2.16.0'
55 MINIMUM_GLIB_VERSION = '2.20.0'
61 mio_sources = set(['tagmanager/mio/mio.c'])
64 'tagmanager/ctags/abaqus.c',
65 'tagmanager/ctags/args.c',
66 'tagmanager/ctags/abc.c',
67 'tagmanager/ctags/actionscript.c',
68 'tagmanager/ctags/asciidoc.c',
69 'tagmanager/ctags/asm.c',
70 'tagmanager/ctags/basic.c',
71 'tagmanager/ctags/c.c',
72 'tagmanager/ctags/cobol.c',
73 'tagmanager/ctags/conf.c',
74 'tagmanager/ctags/css.c',
75 'tagmanager/ctags/ctags.c',
76 'tagmanager/ctags/diff.c',
77 'tagmanager/ctags/docbook.c',
78 'tagmanager/ctags/entry.c',
79 'tagmanager/ctags/fortran.c',
80 'tagmanager/ctags/get.c',
81 'tagmanager/ctags/haskell.c',
82 'tagmanager/ctags/haxe.c',
83 'tagmanager/ctags/html.c',
84 'tagmanager/ctags/js.c',
85 'tagmanager/ctags/keyword.c',
86 'tagmanager/ctags/latex.c',
87 'tagmanager/ctags/lregex.c',
88 'tagmanager/ctags/lua.c',
89 'tagmanager/ctags/make.c',
90 'tagmanager/ctags/markdown.c',
91 'tagmanager/ctags/matlab.c',
92 'tagmanager/ctags/nsis.c',
93 'tagmanager/ctags/nestlevel.c',
94 'tagmanager/ctags/objc.c',
95 'tagmanager/ctags/options.c',
96 'tagmanager/ctags/parse.c',
97 'tagmanager/ctags/pascal.c',
98 'tagmanager/ctags/r.c',
99 'tagmanager/ctags/perl.c',
100 'tagmanager/ctags/php.c',
101 'tagmanager/ctags/python.c',
102 'tagmanager/ctags/read.c',
103 'tagmanager/ctags/rest.c',
104 'tagmanager/ctags/ruby.c',
105 'tagmanager/ctags/sh.c',
106 'tagmanager/ctags/sort.c',
107 'tagmanager/ctags/sql.c',
108 'tagmanager/ctags/strlist.c',
109 'tagmanager/ctags/txt2tags.c',
110 'tagmanager/ctags/tcl.c',
111 'tagmanager/ctags/vhdl.c',
112 'tagmanager/ctags/verilog.c',
113 'tagmanager/ctags/vstring.c'])
115 tagmanager_sources = set([
116 'tagmanager/src/tm_file_entry.c',
117 'tagmanager/src/tm_project.c',
118 'tagmanager/src/tm_source_file.c',
119 'tagmanager/src/tm_symbol.c',
120 'tagmanager/src/tm_tag.c',
121 'tagmanager/src/tm_tagmanager.c',
122 'tagmanager/src/tm_work_object.c',
123 'tagmanager/src/tm_workspace.c'])
125 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
127 geany_sources = set([
128 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
129 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
130 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
131 'src/highlighting.c', 'src/keybindings.c',
132 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
133 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
134 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
136 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
137 'src/ui_utils.c', 'src/utils.c'])
140 'hicolor/16x16/apps': ['16x16/classviewer-class.png',
141 '16x16/classviewer-macro.png',
142 '16x16/classviewer-member.png',
143 '16x16/classviewer-method.png',
144 '16x16/classviewer-namespace.png',
145 '16x16/classviewer-other.png',
146 '16x16/classviewer-struct.png',
147 '16x16/classviewer-var.png',
149 'hicolor/16x16/actions': ['16x16/geany-build.png',
150 '16x16/geany-close-all.png',
151 '16x16/geany-save-all.png'],
152 'hicolor/24x24/actions': ['24x24/geany-build.png',
153 '24x24/geany-close-all.png',
154 '24x24/geany-save-all.png'],
155 'hicolor/32x32/actions': ['32x32/geany-build.png',
156 '32x32/geany-close-all.png',
157 '32x32/geany-save-all.png'],
158 'hicolor/48x48/actions': ['48x48/geany-build.png',
159 '48x48/geany-close-all.png',
160 '48x48/geany-save-all.png'],
161 'hicolor/48x48/apps': ['48x48/geany.png'],
162 'hicolor/scalable/apps': ['scalable/geany.svg'],
163 'hicolor/scalable/actions': ['scalable/geany-build.svg',
164 'scalable/geany-close-all.svg',
165 'scalable/geany-save-all.svg'],
166 'Tango/16x16/actions': ['tango/16x16/geany-save-all.png'],
167 'Tango/24x24/actions': ['tango/24x24/geany-save-all.png'],
168 'Tango/32x32/actions': ['tango/32x32/geany-save-all.png'],
169 'Tango/48x48/actions': ['tango/48x48/geany-save-all.png'],
170 'Tango/scalable/actions': ['tango/scalable/geany-save-all.svg']
172 geany_icons_indexes = {
173 'hicolor': ['index.theme'],
174 'Tango': ['tango/index.theme']
180 conf.check_waf_version(mini='1.6.1')
182 conf.load('compiler_c')
183 is_win32 = _target_is_win32(conf)
185 conf.check_cc(header_name='fcntl.h', mandatory=False)
186 conf.check_cc(header_name='fnmatch.h', mandatory=False)
187 conf.check_cc(header_name='glob.h', mandatory=False)
188 conf.check_cc(header_name='sys/time.h', mandatory=False)
189 conf.check_cc(header_name='sys/types.h', mandatory=False)
190 conf.check_cc(header_name='sys/stat.h', mandatory=False)
191 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
192 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
193 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
195 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
196 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
197 conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
198 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
199 conf.check_cc(function_name='strstr', header_name='string.h')
201 # check sunOS socket support
202 if Options.platform == 'sunos':
203 conf.check_cc(function_name='socket', lib='socket',
204 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
206 # check for cxx after the header and function checks have been done to ensure they are
207 # checked with cc not cxx
208 conf.load('compiler_cxx')
211 _load_intltool_if_available(conf)
213 # GTK / GIO version check
214 conf.check_cfg(package='gtk+-2.0', atleast_version=MINIMUM_GTK_VERSION, uselib_store='GTK',
215 mandatory=True, args='--cflags --libs')
216 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
217 mandatory=True, args='--cflags --libs')
218 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
219 mandatory=True, args='--cflags --libs')
220 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
221 gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK') or 'Unknown'
222 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
226 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
227 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
228 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
229 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
230 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
231 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
232 _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
233 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
234 # overwrite LOCALEDIR to install message catalogues properly
235 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
236 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
237 conf.undefine('DATADIR')
238 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
239 conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
240 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
242 conf.env['cshlib_PATTERN'] = '%s.so'
243 # DATADIR and LOCALEDIR are defined by the intltool tool
244 # but they are not added to the environment, so we need to
245 _add_define_to_env(conf, 'DATADIR')
246 _add_define_to_env(conf, 'LOCALEDIR')
247 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
248 libdir = os.path.join(conf.env['PREFIX'], 'lib')
249 mandir = os.path.join(conf.env['DATADIR'], 'man')
250 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
251 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
252 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
254 revision = _get_git_rev(conf)
256 conf.define('ENABLE_NLS', 1)
257 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
258 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
259 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
260 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
261 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
262 conf.define('PACKAGE', APPNAME, quote=True)
263 conf.define('VERSION', VERSION, quote=True)
264 conf.define('REVISION', revision or '-1', quote=True)
266 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
270 conf.options.no_vte = True
272 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
273 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
274 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
276 conf.write_config_header('config.h', remove=False)
278 # some more compiler flags
279 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
280 if revision is not None:
281 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
283 conf.env.append_value('CFLAGS', ['-DGTK'])
284 conf.env.append_value('CXXFLAGS',
285 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
288 Logs.pprint('BLUE', 'Summary:')
289 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
290 conf.msg('Using GTK version', gtk_version)
291 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
292 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
293 if revision is not None:
294 conf.msg('Compiling Git revision', revision)
298 opt.tool_options('compiler_cc')
299 opt.tool_options('compiler_cxx')
300 opt.tool_options('intltool')
303 opt.add_option('--disable-plugins', action='store_true', default=False,
304 help='compile without plugin support [default: No]', dest='no_plugins')
305 opt.add_option('--disable-socket', action='store_true', default=False,
306 help='compile without support to detect a running instance [[default: No]',
308 opt.add_option('--disable-vte', action='store_true', default=False,
309 help='compile without support for an embedded virtual terminal [[default: No]',
312 opt.add_option('--mandir', type='string', default='',
313 help='man documentation', dest='mandir')
314 opt.add_option('--docdir', type='string', default='',
315 help='documentation root', dest='docdir')
316 opt.add_option('--libdir', type='string', default='',
317 help='object code libraries', dest='libdir')
319 opt.add_option('--hackingdoc', action='store_true', default=False,
320 help='generate HTML documentation from HACKING file', dest='hackingdoc')
324 is_win32 = _target_is_win32(bld)
326 if bld.cmd == 'clean':
327 _remove_linguas_file()
328 if bld.cmd in ('install', 'uninstall'):
329 bld.add_post_fun(_post_install)
331 def build_plugin(plugin_name, install=True):
333 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
338 features = ['c', 'cshlib'],
339 source = 'plugins/%s.c' % plugin_name,
340 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
341 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
342 target = plugin_name,
343 uselib = ['GTK', 'GLIB', 'GMODULE'],
344 install_path = instpath)
348 features = ['c', 'cstlib'],
349 source = ctags_sources,
352 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
353 defines = 'G_LOG_DOMAIN="CTags"',
355 install_path = None) # do not install this library
359 features = ['c', 'cstlib'],
360 source = tagmanager_sources,
362 target = 'tagmanager',
363 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
364 defines = 'G_LOG_DOMAIN="Tagmanager"',
365 uselib = ['GTK', 'GLIB'],
366 install_path = None) # do not install this library
370 features = ['c', 'cstlib'],
371 source = mio_sources,
374 includes = ['.', 'tagmanager/mio/'],
375 defines = 'G_LOG_DOMAIN="MIO"',
376 uselib = ['GTK', 'GLIB'],
377 install_path = None) # do not install this library
380 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
381 scintilla_sources.update(files)
383 features = ['c', 'cxx', 'cxxstlib'],
385 target = 'scintilla',
386 source = scintilla_sources,
387 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
388 uselib = ['GTK', 'GLIB', 'GMODULE'],
389 install_path = None) # do not install this library
392 if bld.env['HAVE_VTE'] == 1:
393 geany_sources.add('src/vte.c')
395 geany_sources.add('src/win32.c')
396 geany_sources.add('geany_private.rc')
399 features = ['c', 'cxx', 'cprogram'],
402 source = geany_sources,
403 includes = ['.', 'scintilla/include', 'tagmanager/src'],
404 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
405 uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
406 use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
410 source = ['plugins/genapi.py', 'src/plugins.c'],
411 name = 'geanyfunctions.h',
412 before = ['c', 'cxx'],
413 cwd = '%s/plugins' % bld.path.abspath(),
414 rule = '%s genapi.py -q' % sys.executable)
417 if bld.env['HAVE_PLUGINS'] == 1:
418 build_plugin('classbuilder')
419 build_plugin('demoplugin', False)
420 build_plugin('export')
421 build_plugin('filebrowser')
422 build_plugin('htmlchars')
423 build_plugin('saveactions')
424 build_plugin('splitwindow')
427 if bld.env['INTLTOOL']:
429 features = ['linguas', 'intltool_po'],
431 install_path = '${LOCALEDIR}',
436 source = 'geany.pc.in',
437 dct = {'VERSION': VERSION,
438 'DEPENDENCIES': 'gtk+-2.0 >= %s glib-2.0 >= %s' % \
439 (MINIMUM_GTK_VERSION, MINIMUM_GLIB_VERSION),
440 'prefix': bld.env['PREFIX'],
441 'exec_prefix': '${prefix}',
442 'libdir': '${exec_prefix}/lib',
443 'includedir': '${prefix}/include',
444 'datarootdir': '${prefix}/share',
445 'datadir': '${datarootdir}',
446 'localedir': '${datarootdir}/locale'})
450 if bld.env['INTLTOOL']:
452 features = 'intltool_in',
453 source = 'geany.desktop.in',
454 flags = ['-d', '-q', '-u', '-c'],
455 install_path = '${DATADIR}/applications')
460 source = 'doc/geany.1.in',
462 dct = {'VERSION': VERSION,
463 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
464 install_path = '${MANDIR}/man1')
469 source = 'geany.spec.in',
470 target = 'geany.spec',
472 dct = {'VERSION': VERSION})
477 source = 'doc/Doxyfile.in',
478 target = 'doc/Doxyfile',
480 dct = {'VERSION': VERSION})
487 bld.install_files('${PREFIX}/include/geany', '''
488 src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
489 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
490 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
491 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h
492 plugins/geanyplugin.h plugins/geanyfunctions.h''')
493 bld.install_files('${PREFIX}/include/geany/scintilla', '''
494 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
495 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
496 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
497 tagmanager/src/tm_file_entry.h tagmanager/src/tm_project.h
498 tagmanager/src/tm_source_file.h
499 tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
500 tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.h
501 tagmanager/src/tm_workspace.h ''')
503 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
504 ext = '.txt' if is_win32 else ''
505 html_dir = '' if is_win32 else 'html/'
506 html_name = 'Manual.html' if is_win32 else 'index.html'
507 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
508 basename = _uc_first(filename, bld)
509 destination_filename = '%s%s' % (basename, ext)
510 destination = os.path.join(base_dir, destination_filename)
511 bld.install_as(destination, filename)
513 start_dir = bld.path.find_dir('doc/images')
514 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
515 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
516 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
517 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
519 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
520 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
522 data_dir = '' if is_win32 else 'geany'
523 start_dir = bld.path.find_dir('data')
524 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
525 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
526 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
527 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
528 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
529 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
530 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
531 start_dir = bld.path.find_dir('data/colorschemes')
532 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
533 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
534 start_dir = bld.path.find_dir('data/templates')
535 template_dest = '${DATADIR}/%s/templates' % data_dir
536 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
538 for dest, srcs in geany_icons.items():
539 dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
540 bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
541 # install theme indexes on Windows
543 for dest, srcs in geany_icons_indexes.items():
544 bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
548 Scripting.distclean(ctx)
549 _remove_linguas_file()
552 def _remove_linguas_file():
553 # remove LINGUAS file as well
555 os.unlink(LINGUAS_FILE)
561 def write_linguas_file(self):
562 if os.path.exists(LINGUAS_FILE):
565 if 'LINGUAS' in self.env:
566 files = self.env['LINGUAS']
567 for po_filename in files.split(' '):
568 if os.path.exists('po/%s.po' % po_filename):
569 linguas += '%s ' % po_filename
571 files = os.listdir('%s/po' % self.path.abspath())
573 for filename in files:
574 if filename.endswith('.po'):
575 linguas += '%s ' % filename[:-3]
576 file_h = open(LINGUAS_FILE, 'w')
577 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
581 def _post_install(ctx):
582 is_win32 = _target_is_win32(ctx)
585 for d in 'hicolor', 'Tango':
586 theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
587 icon_cache_updated = False
588 if not ctx.options.destdir:
589 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
590 Logs.pprint('GREEN', 'GTK icon cache updated.')
591 icon_cache_updated = True
592 if not icon_cache_updated:
593 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
594 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
598 """update the message catalogs for internationalization"""
599 potfile = '%s.pot' % APPNAME
600 os.chdir('%s/po' % top)
603 old_size = os.stat(potfile).st_size
606 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
607 size_new = os.stat(potfile).st_size
608 if size_new != old_size:
609 Logs.pprint('CYAN', 'Updated POT file.')
610 Logs.pprint('CYAN', 'Updating translations')
611 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
613 Logs.pprint('RED', 'Updating translations failed')
615 Logs.pprint('CYAN', 'POT file is up to date.')
617 Logs.pprint('RED', 'Failed to generate pot file.')
621 """generate API reference documentation"""
622 basedir = ctx.path.abspath()
623 doxygen = _find_program(ctx, 'doxygen')
624 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
626 Logs.pprint('CYAN', 'Generating API documentation')
627 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
629 raise WafError('Generating API documentation failed')
630 # update hacking.html
631 cmd = _find_rst2html(ctx)
632 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
637 """generate HTML documentation"""
638 # first try rst2html.py as it is the upstream default, fall back to rst2html
639 cmd = _find_rst2html(ctx)
641 Logs.pprint('CYAN', 'Generating HTML documentation')
642 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
646 def _find_program(ctx, cmd, **kw):
650 ctx = ConfigurationContext()
653 return ctx.find_program(cmd, **kw)
656 def _find_rst2html(ctx):
657 cmds = ['rst2html.py', 'rst2html']
659 cmd = _find_program(ctx, command, mandatory=False)
664 'rst2html.py could not be found. Please install the Python docutils package.')
668 def _add_define_to_env(conf, key):
669 value = conf.get_define(key)
671 value = value.replace('"', '')
672 conf.env[key] = value
675 def _add_to_env_and_define(conf, key, value, quote=False):
676 conf.define(key, value, quote)
677 conf.env[key] = value
680 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
681 value = default_value
683 if isinstance(opt_value, bool):
687 if value is not None:
688 _add_to_env_and_define(conf, define_name, value, quote)
690 conf.undefine(define_name)
693 def _get_git_rev(conf):
694 if not os.path.isdir('.git'):
698 cmd = 'git rev-parse --short --revs-only HEAD'
699 revision = conf.cmd_and_log(cmd).strip()
706 def _load_intltool_if_available(conf):
708 conf.check_tool('intltool')
709 if 'LINGUAS' in os.environ:
710 conf.env['LINGUAS'] = os.environ['LINGUAS']
712 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
713 if not _target_is_win32(conf):
717 def _target_is_win32(ctx):
718 if 'is_win32' in ctx.env:
720 return ctx.env['is_win32']
722 if sys.platform == 'win32':
725 if ctx.env and 'CC' in ctx.env:
726 env_cc = ctx.env['CC']
727 if not isinstance(env_cc, str):
728 env_cc = ''.join(env_cc)
729 is_win32 = (env_cc.find('mingw') != -1)
732 # cache for future checks
733 ctx.env['is_win32'] = is_win32
737 def _uc_first(string, ctx):
738 if _target_is_win32(ctx):
739 return string.title()