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/args.c',
65 'tagmanager/ctags/abc.c',
66 'tagmanager/ctags/actionscript.c',
67 'tagmanager/ctags/asm.c',
68 'tagmanager/ctags/basic.c',
69 'tagmanager/ctags/c.c',
70 'tagmanager/ctags/cobol.c',
71 'tagmanager/ctags/conf.c',
72 'tagmanager/ctags/css.c',
73 'tagmanager/ctags/ctags.c',
74 'tagmanager/ctags/diff.c',
75 'tagmanager/ctags/docbook.c',
76 'tagmanager/ctags/entry.c',
77 'tagmanager/ctags/fortran.c',
78 'tagmanager/ctags/get.c',
79 'tagmanager/ctags/haskell.c',
80 'tagmanager/ctags/haxe.c',
81 'tagmanager/ctags/html.c',
82 'tagmanager/ctags/js.c',
83 'tagmanager/ctags/keyword.c',
84 'tagmanager/ctags/latex.c',
85 'tagmanager/ctags/lregex.c',
86 'tagmanager/ctags/lua.c',
87 'tagmanager/ctags/make.c',
88 'tagmanager/ctags/markdown.c',
89 'tagmanager/ctags/matlab.c',
90 'tagmanager/ctags/nsis.c',
91 'tagmanager/ctags/nestlevel.c',
92 'tagmanager/ctags/objc.c',
93 'tagmanager/ctags/options.c',
94 'tagmanager/ctags/parse.c',
95 'tagmanager/ctags/pascal.c',
96 'tagmanager/ctags/r.c',
97 'tagmanager/ctags/perl.c',
98 'tagmanager/ctags/php.c',
99 'tagmanager/ctags/python.c',
100 'tagmanager/ctags/read.c',
101 'tagmanager/ctags/rest.c',
102 'tagmanager/ctags/ruby.c',
103 'tagmanager/ctags/sh.c',
104 'tagmanager/ctags/sort.c',
105 'tagmanager/ctags/sql.c',
106 'tagmanager/ctags/strlist.c',
107 'tagmanager/ctags/txt2tags.c',
108 'tagmanager/ctags/tcl.c',
109 'tagmanager/ctags/vhdl.c',
110 'tagmanager/ctags/verilog.c',
111 'tagmanager/ctags/vstring.c'])
113 tagmanager_sources = set([
114 'tagmanager/src/tm_file_entry.c',
115 'tagmanager/src/tm_project.c',
116 'tagmanager/src/tm_source_file.c',
117 'tagmanager/src/tm_symbol.c',
118 'tagmanager/src/tm_tag.c',
119 'tagmanager/src/tm_tagmanager.c',
120 'tagmanager/src/tm_work_object.c',
121 'tagmanager/src/tm_workspace.c'])
123 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
125 geany_sources = set([
126 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
127 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
128 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
129 'src/highlighting.c', 'src/keybindings.c',
130 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
131 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
132 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
134 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
135 'src/ui_utils.c', 'src/utils.c'])
140 conf.check_waf_version(mini='1.6.1')
142 conf.load('compiler_c')
143 is_win32 = _target_is_win32(conf)
145 conf.check_cc(header_name='fcntl.h', mandatory=False)
146 conf.check_cc(header_name='fnmatch.h', mandatory=False)
147 conf.check_cc(header_name='glob.h', mandatory=False)
148 conf.check_cc(header_name='sys/time.h', mandatory=False)
149 conf.check_cc(header_name='sys/types.h', mandatory=False)
150 conf.check_cc(header_name='sys/stat.h', mandatory=False)
151 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
152 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
153 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
155 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
156 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
157 conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
158 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
159 conf.check_cc(function_name='strstr', header_name='string.h')
161 # check sunOS socket support
162 if Options.platform == 'sunos':
163 conf.check_cc(function_name='socket', lib='socket',
164 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
166 # check for cxx after the header and function checks have been done to ensure they are
167 # checked with cc not cxx
168 conf.load('compiler_cxx')
171 _load_intltool_if_available(conf)
173 # GTK / GIO version check
174 conf.check_cfg(package='gtk+-2.0', atleast_version=MINIMUM_GTK_VERSION, uselib_store='GTK',
175 mandatory=True, args='--cflags --libs')
176 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
177 mandatory=True, args='--cflags --libs')
178 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
179 mandatory=True, args='--cflags --libs')
180 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
181 gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK') or 'Unknown'
182 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
186 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
187 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
188 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
189 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
190 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
191 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
192 _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
193 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
194 # overwrite LOCALEDIR to install message catalogues properly
195 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
196 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
197 conf.undefine('DATADIR')
198 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
199 conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
200 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
202 conf.env['cshlib_PATTERN'] = '%s.so'
203 # DATADIR and LOCALEDIR are defined by the intltool tool
204 # but they are not added to the environment, so we need to
205 _add_define_to_env(conf, 'DATADIR')
206 _add_define_to_env(conf, 'LOCALEDIR')
207 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
208 libdir = os.path.join(conf.env['PREFIX'], 'lib')
209 mandir = os.path.join(conf.env['DATADIR'], 'man')
210 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
211 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
212 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
214 revision = _get_git_rev(conf)
216 conf.define('ENABLE_NLS', 1)
217 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
218 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
219 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
220 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
221 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
222 conf.define('PACKAGE', APPNAME, quote=True)
223 conf.define('VERSION', VERSION, quote=True)
224 conf.define('REVISION', revision or '-1', quote=True)
226 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
230 conf.options.no_vte = True
232 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
233 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
234 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
236 conf.write_config_header('config.h', remove=False)
238 # some more compiler flags
239 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
240 if revision is not None:
241 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
243 conf.env.append_value('CFLAGS', ['-DGTK'])
244 conf.env.append_value('CXXFLAGS',
245 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
248 Logs.pprint('BLUE', 'Summary:')
249 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
250 conf.msg('Using GTK version', gtk_version)
251 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
252 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
253 if revision is not None:
254 conf.msg('Compiling Git revision', revision)
258 opt.tool_options('compiler_cc')
259 opt.tool_options('compiler_cxx')
260 opt.tool_options('intltool')
263 opt.add_option('--disable-plugins', action='store_true', default=False,
264 help='compile without plugin support [default: No]', dest='no_plugins')
265 opt.add_option('--disable-socket', action='store_true', default=False,
266 help='compile without support to detect a running instance [[default: No]',
268 opt.add_option('--disable-vte', action='store_true', default=False,
269 help='compile without support for an embedded virtual terminal [[default: No]',
272 opt.add_option('--mandir', type='string', default='',
273 help='man documentation', dest='mandir')
274 opt.add_option('--docdir', type='string', default='',
275 help='documentation root', dest='docdir')
276 opt.add_option('--libdir', type='string', default='',
277 help='object code libraries', dest='libdir')
279 opt.add_option('--hackingdoc', action='store_true', default=False,
280 help='generate HTML documentation from HACKING file', dest='hackingdoc')
284 is_win32 = _target_is_win32(bld)
286 if bld.cmd == 'clean':
287 _remove_linguas_file()
288 if bld.cmd in ('install', 'uninstall'):
289 bld.add_post_fun(_post_install)
291 def build_plugin(plugin_name, install=True):
293 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
298 features = ['c', 'cshlib'],
299 source = 'plugins/%s.c' % plugin_name,
300 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
301 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
302 target = plugin_name,
303 uselib = ['GTK', 'GLIB', 'GMODULE'],
304 install_path = instpath)
308 features = ['c', 'cstlib'],
309 source = ctags_sources,
312 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
313 defines = 'G_LOG_DOMAIN="CTags"',
315 install_path = None) # do not install this library
319 features = ['c', 'cstlib'],
320 source = tagmanager_sources,
322 target = 'tagmanager',
323 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
324 defines = 'G_LOG_DOMAIN="Tagmanager"',
325 uselib = ['GTK', 'GLIB'],
326 install_path = None) # do not install this library
330 features = ['c', 'cstlib'],
331 source = mio_sources,
334 includes = ['.', 'tagmanager/mio/'],
335 defines = 'G_LOG_DOMAIN="MIO"',
336 uselib = ['GTK', 'GLIB'],
337 install_path = None) # do not install this library
340 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
341 scintilla_sources.update(files)
343 features = ['c', 'cxx', 'cxxstlib'],
345 target = 'scintilla',
346 source = scintilla_sources,
347 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
348 uselib = ['GTK', 'GLIB', 'GMODULE'],
349 install_path = None) # do not install this library
352 if bld.env['HAVE_VTE'] == 1:
353 geany_sources.add('src/vte.c')
355 geany_sources.add('src/win32.c')
356 geany_sources.add('geany_private.rc')
359 features = ['c', 'cxx', 'cprogram'],
362 source = geany_sources,
363 includes = ['.', 'scintilla/include', 'tagmanager/src'],
364 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
365 linkflags = [] if is_win32 else ['-Wl,--export-dynamic'],
366 uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
367 use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
371 source = ['plugins/genapi.py', 'src/plugins.c'],
372 name = 'geanyfunctions.h',
373 before = ['c', 'cxx'],
374 cwd = '%s/plugins' % bld.path.abspath(),
375 rule = '%s genapi.py -q' % sys.executable)
378 if bld.env['HAVE_PLUGINS'] == 1:
379 build_plugin('classbuilder')
380 build_plugin('demoplugin', False)
381 build_plugin('export')
382 build_plugin('filebrowser')
383 build_plugin('htmlchars')
384 build_plugin('saveactions')
385 build_plugin('splitwindow')
388 if bld.env['INTLTOOL']:
390 features = ['linguas', 'intltool_po'],
392 install_path = '${LOCALEDIR}',
397 source = 'geany.pc.in',
398 dct = {'VERSION': VERSION,
399 'DEPENDENCIES': 'gtk+-2.0 >= %s glib-2.0 >= %s' % \
400 (MINIMUM_GTK_VERSION, MINIMUM_GLIB_VERSION),
401 'prefix': bld.env['PREFIX'],
402 'exec_prefix': '${prefix}',
403 'libdir': '${exec_prefix}/lib',
404 'includedir': '${prefix}/include',
405 'datarootdir': '${prefix}/share',
406 'datadir': '${datarootdir}',
407 'localedir': '${datarootdir}/locale'})
411 if bld.env['INTLTOOL']:
413 features = 'intltool_in',
414 source = 'geany.desktop.in',
415 flags = ['-d', '-q', '-u', '-c'],
416 install_path = '${DATADIR}/applications')
421 source = 'doc/geany.1.in',
423 dct = {'VERSION': VERSION,
424 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
425 install_path = '${MANDIR}/man1')
430 source = 'geany.spec.in',
431 target = 'geany.spec',
433 dct = {'VERSION': VERSION})
438 source = 'doc/Doxyfile.in',
439 target = 'doc/Doxyfile',
441 dct = {'VERSION': VERSION})
448 bld.install_files('${PREFIX}/include/geany', '''
449 src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
450 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
451 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
452 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h
453 plugins/geanyplugin.h plugins/geanyfunctions.h''')
454 bld.install_files('${PREFIX}/include/geany/scintilla', '''
455 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
456 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
457 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
458 tagmanager/src/tm_file_entry.h tagmanager/src/tm_project.h
459 tagmanager/src/tm_source_file.h
460 tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
461 tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.h
462 tagmanager/src/tm_workspace.h ''')
464 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
465 ext = '.txt' if is_win32 else ''
466 html_dir = '' if is_win32 else 'html/'
467 html_name = 'Manual.html' if is_win32 else 'index.html'
468 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
469 basename = _uc_first(filename, bld)
470 destination_filename = '%s%s' % (basename, ext)
471 destination = os.path.join(base_dir, destination_filename)
472 bld.install_as(destination, filename)
474 start_dir = bld.path.find_dir('doc/images')
475 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
476 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
477 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
478 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
480 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
481 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
483 data_dir = '' if is_win32 else 'geany'
484 start_dir = bld.path.find_dir('data')
485 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
486 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
487 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
488 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
489 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
490 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
491 start_dir = bld.path.find_dir('data/colorschemes')
492 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
493 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
494 start_dir = bld.path.find_dir('data/templates')
495 template_dest = '${DATADIR}/%s/templates' % data_dir
496 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
498 icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
499 start_dir = bld.path.find_dir('icons/16x16')
500 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
502 start_dir = bld.path.find_dir('icons/48x48')
503 icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
504 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
505 start_dir = bld.path.find_dir('icons/scalable')
506 scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
507 bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
511 Scripting.distclean(ctx)
512 _remove_linguas_file()
515 def _remove_linguas_file():
516 # remove LINGUAS file as well
518 os.unlink(LINGUAS_FILE)
524 def write_linguas_file(self):
525 if os.path.exists(LINGUAS_FILE):
528 if 'LINGUAS' in self.env:
529 files = self.env['LINGUAS']
530 for po_filename in files.split(' '):
531 if os.path.exists('po/%s.po' % po_filename):
532 linguas += '%s ' % po_filename
534 files = os.listdir('%s/po' % self.path.abspath())
536 for filename in files:
537 if filename.endswith('.po'):
538 linguas += '%s ' % filename[:-3]
539 file_h = open(LINGUAS_FILE, 'w')
540 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
544 def _post_install(ctx):
545 is_win32 = _target_is_win32(ctx)
548 theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
549 icon_cache_updated = False
550 if not ctx.options.destdir:
551 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
552 Logs.pprint('GREEN', 'GTK icon cache updated.')
553 icon_cache_updated = True
554 if not icon_cache_updated:
555 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
556 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
560 """update the message catalogs for internationalization"""
561 potfile = '%s.pot' % APPNAME
562 os.chdir('%s/po' % top)
565 old_size = os.stat(potfile).st_size
568 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
569 size_new = os.stat(potfile).st_size
570 if size_new != old_size:
571 Logs.pprint('CYAN', 'Updated POT file.')
572 Logs.pprint('CYAN', 'Updating translations')
573 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
575 Logs.pprint('RED', 'Updating translations failed')
577 Logs.pprint('CYAN', 'POT file is up to date.')
579 Logs.pprint('RED', 'Failed to generate pot file.')
583 """generate API reference documentation"""
584 basedir = ctx.path.abspath()
585 doxygen = _find_program(ctx, 'doxygen')
586 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
588 Logs.pprint('CYAN', 'Generating API documentation')
589 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
591 raise WafError('Generating API documentation failed')
592 # update hacking.html
593 cmd = _find_rst2html(ctx)
594 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
599 """generate HTML documentation"""
600 # first try rst2html.py as it is the upstream default, fall back to rst2html
601 cmd = _find_rst2html(ctx)
603 Logs.pprint('CYAN', 'Generating HTML documentation')
604 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
608 def _find_program(ctx, cmd, **kw):
612 ctx = ConfigurationContext()
615 return ctx.find_program(cmd, **kw)
618 def _find_rst2html(ctx):
619 cmds = ['rst2html.py', 'rst2html']
621 cmd = _find_program(ctx, command, mandatory=False)
626 'rst2html.py could not be found. Please install the Python docutils package.')
630 def _add_define_to_env(conf, key):
631 value = conf.get_define(key)
633 value = value.replace('"', '')
634 conf.env[key] = value
637 def _add_to_env_and_define(conf, key, value, quote=False):
638 conf.define(key, value, quote)
639 conf.env[key] = value
642 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
643 value = default_value
645 if isinstance(opt_value, bool):
649 if value is not None:
650 _add_to_env_and_define(conf, define_name, value, quote)
652 conf.undefine(define_name)
655 def _get_git_rev(conf):
656 if not os.path.isdir('.git'):
660 cmd = 'git rev-parse --short --revs-only HEAD'
661 revision = conf.cmd_and_log(cmd).strip()
668 def _load_intltool_if_available(conf):
670 conf.check_tool('intltool')
671 if 'LINGUAS' in os.environ:
672 conf.env['LINGUAS'] = os.environ['LINGUAS']
674 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
675 if not _target_is_win32(conf):
679 def _target_is_win32(ctx):
680 if 'is_win32' in ctx.env:
682 return ctx.env['is_win32']
684 if sys.platform == 'win32':
687 if ctx.env and 'CC' in ctx.env:
688 env_cc = ctx.env['CC']
689 if not isinstance(env_cc, str):
690 env_cc = ''.join(env_cc)
691 is_win32 = (env_cc.find('mingw') != -1)
694 # cache for future checks
695 ctx.env['is_win32'] = is_win32
699 def _uc_first(string, ctx):
700 if _target_is_win32(ctx):
701 return string.title()