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.
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 ConfigurationError, WafError
48 from waflib.TaskGen import feature
53 LINGUAS_FILE = 'po/LINGUAS'
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'])
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',
90 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
91 'src/ui_utils.c', 'src/utils.c'])
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)
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')
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')
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'])
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)
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'])
208 conf.env.append_value('CFLAGS', ['-DGTK'])
209 conf.env.append_value('CXXFLAGS',
210 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
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)
224 opt.tool_options('compiler_cc')
225 opt.tool_options('compiler_cxx')
226 opt.tool_options('intltool')
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]',
234 opt.add_option('--disable-vte', action='store_true', default=False,
235 help='compile without support for an embedded virtual terminal [[default: No]',
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')
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')
247 opt.add_option('--hackingdoc', action='store_true', default=False,
248 help='generate HTML documentation from HACKING file', dest='hackingdoc')
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):
261 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
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)
276 if bld.env['USE_INCLUDED_REGEX'] == 1:
277 tagmanager_sources.add('tagmanager/regex.c')
279 features = ['c', 'cstlib'],
280 source = tagmanager_sources,
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
291 features = ['c', 'cstlib'],
292 source = mio_sources,
295 includes = ['.', 'tagmanager/mio/'],
296 defines = 'G_LOG_DOMAIN="MIO"',
297 uselib = ['GTK', 'GLIB'],
298 install_path = None) # do not install this library
302 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
303 scintilla_sources.update(files)
305 features = ['c', 'cxx', 'cxxstlib'],
307 target = 'scintilla',
308 source = scintilla_sources,
309 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
311 install_path = None) # do not install this library
315 if bld.env['HAVE_VTE'] == 1:
316 geany_sources.add('src/vte.c')
318 geany_sources.add('src/win32.c')
319 geany_sources.add('geany_private.rc')
322 features = ['c', 'cxx', 'cprogram'],
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'])
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')
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')
351 if bld.env['INTLTOOL']:
353 features = ['linguas', 'intltool_po'],
355 install_path = '${LOCALEDIR}',
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'})
372 if bld.env['INTLTOOL']:
374 features = 'intltool_in',
375 source = 'geany.desktop.in',
376 flags = [ '-d', '-q', '-u', '-c' ],
377 install_path = '${DATADIR}/applications')
382 source = 'doc/geany.1.in',
384 dct = {'VERSION' : VERSION,
385 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
386 install_path = '${MANDIR}/man1')
391 source = 'geany.spec.in',
392 target = 'geany.spec',
394 dct = {'VERSION' : VERSION})
399 source = 'doc/Doxyfile.in',
400 target = 'doc/Doxyfile',
402 dct = {'VERSION' : VERSION})
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 ''')
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')
441 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
442 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
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)
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)
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)
472 Scripting.distclean(ctx)
473 _remove_linguas_file()
476 def _remove_linguas_file():
477 # remove LINGUAS file as well
479 os.unlink(LINGUAS_FILE)
485 def write_linguas_file(self):
486 if os.path.exists(LINGUAS_FILE):
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
495 files = os.listdir('%s/po' % self.path.abspath())
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)
505 def _post_install(ctx):
506 is_win32 = _target_is_win32(ctx)
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)
521 """update the message catalogs for internationalization"""
522 potfile = '%s.pot' % APPNAME
523 os.chdir('%s/po' % top)
526 old_size = os.stat(potfile).st_size
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)
536 Logs.pprint('RED', 'Updating translations failed')
538 Logs.pprint('CYAN', 'POT file is up to date.')
540 Logs.pprint('RED', 'Failed to generate pot file.')
544 """generate API reference documentation"""
545 basedir = ctx.path.abspath()
546 doxygen = _find_program(ctx, 'doxygen')
547 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
549 Logs.pprint('CYAN', 'Generating API documentation')
550 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
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'))
560 """generate HTML documentation"""
561 # first try rst2html.py as it is the upstream default, fall back to rst2html
562 cmd = _find_rst2html(ctx)
564 Logs.pprint('CYAN', 'Generating HTML documentation')
565 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
569 def _find_program(ctx, cmd, **kw):
573 ctx = ConfigurationContext()
576 return ctx.find_program(cmd, **kw)
579 def _find_rst2html(ctx):
580 cmds = ['rst2html.py', 'rst2html']
582 cmd = _find_program(ctx, command, mandatory=False)
587 'rst2html.py could not be found. Please install the Python docutils package.')
591 def _add_define_to_env(conf, key):
592 value = conf.get_define(key)
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
606 if isinstance(opt_value, bool):
610 if value is not None:
611 _add_to_env_and_define(conf, define_name, value, quote)
613 conf.undefine(define_name)
616 def _get_git_rev(conf):
617 if not os.path.isdir('.git'):
621 cmd = 'git rev-parse --short --revs-only HEAD'
622 revision = conf.cmd_and_log(cmd).strip()
629 def _load_intltool_if_available(conf):
631 conf.check_tool('intltool')
632 if 'LINGUAS' in os.environ:
633 conf.env['LINGUAS'] = os.environ['LINGUAS']
635 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
636 if not _target_is_win32(conf):
640 def _target_is_win32(ctx):
641 if 'is_win32' in ctx.env:
643 return ctx.env['is_win32']
645 if sys.platform == 'win32':
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)
655 # cache for future checks
656 ctx.env['is_win32'] = is_win32
660 def _uc_first(string, ctx):
661 if _target_is_win32(ctx):
662 return string.title()