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/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/interface.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.12.0', uselib_store='GTK',
142 mandatory=True, args='--cflags --libs')
143 conf.check_cfg(package='glib-2.0', atleast_version='2.16.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 uselib = ['GTK', 'GLIB', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
329 use = ['scintilla', 'tagmanager', 'mio'])
333 source = ['plugins/genapi.py', 'src/plugins.c'],
334 name = 'geanyfunctions.h',
335 before = ['c', 'cxx'],
336 cwd = '%s/plugins' % bld.path.abspath(),
337 rule = 'python genapi.py -q')
340 if bld.env['HAVE_PLUGINS'] == 1:
341 build_plugin('classbuilder')
342 build_plugin('demoplugin', False)
343 build_plugin('export')
344 build_plugin('filebrowser')
345 build_plugin('htmlchars')
346 build_plugin('saveactions')
347 build_plugin('splitwindow')
350 if bld.env['INTLTOOL']:
352 features = ['linguas', 'intltool_po'],
354 install_path = '${LOCALEDIR}',
359 source = 'geany.pc.in',
360 dct = {'VERSION' : VERSION,
361 'prefix': bld.env['PREFIX'],
362 'exec_prefix': '${prefix}',
363 'libdir': '${exec_prefix}/lib',
364 'includedir': '${prefix}/include',
365 'datarootdir': '${prefix}/share',
366 'datadir': '${datarootdir}',
367 'localedir': '${datarootdir}/locale'})
371 if bld.env['INTLTOOL']:
373 features = 'intltool_in',
374 source = 'geany.desktop.in',
375 flags = [ '-d', '-q', '-u', '-c' ],
376 install_path = '${DATADIR}/applications')
381 source = 'doc/geany.1.in',
383 dct = {'VERSION' : VERSION,
384 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
385 install_path = '${MANDIR}/man1')
390 source = 'geany.spec.in',
391 target = 'geany.spec',
393 dct = {'VERSION' : VERSION})
398 source = 'doc/Doxyfile.in',
399 target = 'doc/Doxyfile',
401 dct = {'VERSION' : VERSION})
408 bld.install_files('${PREFIX}/include/geany', '''
409 src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
410 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
411 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
412 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h
413 plugins/geanyplugin.h plugins/geanyfunctions.h''')
414 bld.install_files('${PREFIX}/include/geany/scintilla', '''
415 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
416 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
417 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
418 tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
419 tagmanager/include/tm_source_file.h
420 tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
421 tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
422 tagmanager/include/tm_workspace.h ''')
424 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
425 ext = '.txt' if is_win32 else ''
426 html_dir = '' if is_win32 else 'html/'
427 html_name = 'Manual.html' if is_win32 else 'index.html'
428 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
429 basename = _uc_first(filename, bld)
430 destination_filename = '%s%s' % (basename, ext)
431 destination = os.path.join(base_dir, destination_filename)
432 bld.install_as(destination, filename)
434 start_dir = bld.path.find_dir('doc/images')
435 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
436 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
437 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
438 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
440 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
441 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
443 data_dir = '' if is_win32 else 'geany'
444 start_dir = bld.path.find_dir('data')
445 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
446 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
447 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
448 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
449 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
450 start_dir = bld.path.find_dir('data/colorschemes')
451 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
452 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
453 start_dir = bld.path.find_dir('data/templates')
454 template_dest = '${DATADIR}/%s/templates' % data_dir
455 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
457 icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
458 start_dir = bld.path.find_dir('icons/16x16')
459 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
461 start_dir = bld.path.find_dir('icons/48x48')
462 icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
463 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
464 start_dir = bld.path.find_dir('icons/scalable')
465 scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
466 bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
470 Scripting.distclean(ctx)
471 _remove_linguas_file()
474 def _remove_linguas_file():
475 # remove LINGUAS file as well
477 os.unlink(LINGUAS_FILE)
483 def write_linguas_file(self):
484 if os.path.exists(LINGUAS_FILE):
487 if 'LINGUAS' in self.env:
488 files = self.env['LINGUAS']
489 for po_filename in files.split(' '):
490 if os.path.exists ('po/%s.po' % po_filename):
491 linguas += '%s ' % po_filename
493 files = os.listdir('%s/po' % self.path.abspath())
495 for filename in files:
496 if filename.endswith('.po'):
497 linguas += '%s ' % filename[:-3]
498 file_h = open(LINGUAS_FILE, 'w')
499 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
503 def _post_install(ctx):
504 is_win32 = _target_is_win32(ctx)
507 theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
508 icon_cache_updated = False
509 if not ctx.options.destdir:
510 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
511 Logs.pprint('GREEN', 'GTK icon cache updated.')
512 icon_cache_updated = True
513 if not icon_cache_updated:
514 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
515 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
519 """update the message catalogs for internationalization"""
520 potfile = '%s.pot' % APPNAME
521 os.chdir('%s/po' % top)
524 old_size = os.stat(potfile).st_size
527 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
528 size_new = os.stat(potfile).st_size
529 if size_new != old_size:
530 Logs.pprint('CYAN', 'Updated POT file.')
531 Logs.pprint('CYAN', 'Updating translations')
532 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
534 Logs.pprint('RED', 'Updating translations failed')
536 Logs.pprint('CYAN', 'POT file is up to date.')
538 Logs.pprint('RED', 'Failed to generate pot file.')
542 """generate API reference documentation"""
543 basedir = ctx.path.abspath()
544 doxygen = _find_program(ctx, 'doxygen')
545 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
547 Logs.pprint('CYAN', 'Generating API documentation')
548 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
550 raise WafError('Generating API documentation failed')
551 # update hacking.html
552 cmd = _find_rst2html(ctx)
553 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
558 """generate HTML documentation"""
559 # first try rst2html.py as it is the upstream default, fall back to rst2html
560 cmd = _find_rst2html(ctx)
562 Logs.pprint('CYAN', 'Generating HTML documentation')
563 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
567 def _find_program(ctx, cmd, **kw):
571 ctx = ConfigurationContext()
574 return ctx.find_program(cmd, **kw)
577 def _find_rst2html(ctx):
578 cmds = ['rst2html.py', 'rst2html']
580 cmd = _find_program(ctx, command, mandatory=False)
585 'rst2html.py could not be found. Please install the Python docutils package.')
589 def _add_define_to_env(conf, key):
590 value = conf.get_define(key)
592 value = value.replace('"', '')
593 conf.env[key] = value
596 def _add_to_env_and_define(conf, key, value, quote=False):
597 conf.define(key, value, quote)
598 conf.env[key] = value
601 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
602 value = default_value
604 if isinstance(opt_value, bool):
608 if value is not None:
609 _add_to_env_and_define(conf, define_name, value, quote)
611 conf.undefine(define_name)
614 def _get_git_rev(conf):
615 if not os.path.isdir('.git'):
619 cmd = 'git rev-parse --short --revs-only HEAD'
620 revision = conf.cmd_and_log(cmd).strip()
627 def _load_intltool_if_available(conf):
629 conf.check_tool('intltool')
630 if 'LINGUAS' in os.environ:
631 conf.env['LINGUAS'] = os.environ['LINGUAS']
633 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
634 if not _target_is_win32(conf):
638 def _target_is_win32(ctx):
639 if 'is_win32' in ctx.env:
641 return ctx.env['is_win32']
643 if sys.platform == 'win32':
646 if ctx.env and 'CC' in ctx.env:
647 env_cc = ctx.env['CC']
648 if not isinstance(env_cc, str):
649 env_cc = ''.join(env_cc)
650 is_win32 = (env_cc.find('mingw') != -1)
653 # cache for future checks
654 ctx.env['is_win32'] = is_win32
658 def _uc_first(string, ctx):
659 if _target_is_win32(ctx):
660 return string.title()