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.
25 This is a WAF build script (http://code.google.com/p/waf/).
26 It can be used as an alternative build system to autotools
27 for Geany. It does not (yet) cover all of the autotools tests and
28 configure options but all important things are working.
29 "make dist" should be done with autotools, most other targets and
30 functions should work better (regarding performance and flexibility)
33 Missing features: --enable-binreloc, make targets: dist, pdf (in doc/)
34 Known issues: Dependency handling is buggy, e.g. if src/document.h is
35 changed, depending source files are not rebuilt (maybe Waf bug).
37 The code of this file itself loosely follows PEP 8 with some exceptions
38 (line width 100 characters and some other minor things).
40 Requires WAF 1.6.1 and Python 2.5 (or later).
47 from distutils import version
48 from waflib import Logs, Options, Scripting, Utils
49 from waflib.Configure import ConfigurationContext
50 from waflib.Errors import ConfigurationError, WafError
51 from waflib.TaskGen import feature
56 LINGUAS_FILE = 'po/LINGUAS'
62 mio_sources = set(['tagmanager/mio/mio.c'])
64 tagmanager_sources = set([
65 'tagmanager/args.c', 'tagmanager/abc.c', 'tagmanager/actionscript.c', 'tagmanager/asm.c',
66 'tagmanager/basic.c', 'tagmanager/c.c', 'tagmanager/cobol.c',
67 'tagmanager/conf.c', 'tagmanager/css.c', 'tagmanager/ctags.c', 'tagmanager/diff.c',
68 'tagmanager/docbook.c', 'tagmanager/entry.c', 'tagmanager/fortran.c', 'tagmanager/get.c',
69 'tagmanager/haskell.c', 'tagmanager/haxe.c', 'tagmanager/html.c', 'tagmanager/js.c',
70 'tagmanager/keyword.c', 'tagmanager/latex.c', 'tagmanager/lregex.c', 'tagmanager/lua.c',
71 'tagmanager/make.c', 'tagmanager/markdown.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
72 'tagmanager/nestlevel.c', 'tagmanager/options.c',
73 'tagmanager/parse.c', 'tagmanager/pascal.c', 'tagmanager/r.c',
74 'tagmanager/perl.c', 'tagmanager/php.c', 'tagmanager/python.c', 'tagmanager/read.c',
75 'tagmanager/rest.c', 'tagmanager/ruby.c', 'tagmanager/sh.c', 'tagmanager/sort.c',
76 'tagmanager/sql.c', 'tagmanager/strlist.c', 'tagmanager/txt2tags.c', 'tagmanager/tcl.c',
77 'tagmanager/tm_file_entry.c',
78 'tagmanager/tm_project.c', 'tagmanager/tm_source_file.c', 'tagmanager/tm_symbol.c',
79 'tagmanager/tm_tag.c', 'tagmanager/tm_tagmanager.c', 'tagmanager/tm_work_object.c',
80 'tagmanager/tm_workspace.c', 'tagmanager/vhdl.c', 'tagmanager/verilog.c', 'tagmanager/vstring.c'])
82 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
85 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
86 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
87 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
88 'src/highlighting.c', 'src/interface.c', 'src/keybindings.c',
89 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
90 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
91 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
93 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
94 'src/ui_utils.c', 'src/utils.c'])
100 conf.check_waf_version(mini='1.6.1')
102 conf.load('compiler_c')
103 is_win32 = _target_is_win32(conf)
105 conf.check_cc(header_name='fcntl.h', mandatory=False)
106 conf.check_cc(header_name='fnmatch.h', mandatory=False)
107 conf.check_cc(header_name='glob.h', mandatory=False)
108 conf.check_cc(header_name='sys/time.h', mandatory=False)
109 conf.check_cc(header_name='sys/types.h', mandatory=False)
110 conf.check_cc(header_name='sys/stat.h', mandatory=False)
111 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
112 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
114 if conf.options.gnu_regex:
115 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
116 _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
119 conf.check_cc(header_name='regex.h')
120 conf.check_cc(function_name='regcomp', header_name='regex.h')
121 except ConfigurationError:
122 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
123 _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
125 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
126 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
127 conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
128 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
129 conf.check_cc(function_name='strstr', header_name='string.h')
131 # check sunOS socket support
132 if Options.platform == 'sunos':
133 conf.check_cc(function_name='socket', lib='socket',
134 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
136 # check for cxx after the header and function checks have been done to ensure they are
137 # checked with cc not cxx
138 conf.load('compiler_cxx')
141 _load_intltool_if_available(conf)
143 # GTK / GIO version check
144 conf.check_cfg(package='gtk+-2.0', atleast_version='2.8.0', uselib_store='GTK',
145 mandatory=True, args='--cflags --libs')
147 gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK')
149 if version.LooseVersion(gtk_version) >= version.LooseVersion('2.10.0'):
152 gtk_version = 'Unknown'
153 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
154 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=False)
158 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
159 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
160 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
161 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
162 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
163 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
164 _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
165 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
166 # overwrite LOCALEDIR to install message catalogues properly
167 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
168 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
169 conf.undefine('DATADIR')
170 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
171 conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
172 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
174 conf.env['cshlib_PATTERN'] = '%s.so'
175 # DATADIR and LOCALEDIR are defined by the intltool tool
176 # but they are not added to the environment, so we need to
177 _add_define_to_env(conf, 'DATADIR')
178 _add_define_to_env(conf, 'LOCALEDIR')
179 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
180 libdir = os.path.join(conf.env['PREFIX'], 'lib')
181 mandir = os.path.join(conf.env['DATADIR'], 'man')
182 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
183 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
184 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
186 svn_rev = _get_svn_rev(conf)
188 conf.define('ENABLE_NLS', 1)
189 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
190 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
191 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
192 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
193 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
194 conf.define('PACKAGE', APPNAME, quote=True)
195 conf.define('VERSION', VERSION, quote=True)
196 conf.define('REVISION', str(svn_rev), quote=True)
198 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
202 conf.options.no_vte = True
204 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
205 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
206 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
208 conf.write_config_header('config.h', remove=False)
210 # some more compiler flags
211 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
213 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
215 conf.env.append_value('CFLAGS', ['-DGTK'])
216 conf.env.append_value('CXXFLAGS',
217 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
220 Logs.pprint('BLUE', 'Summary:')
221 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
222 conf.msg('Using GTK version', gtk_version)
223 conf.msg('Build with GTK printing support', have_gtk_210 and 'yes' or 'no')
224 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
225 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
226 conf.msg('GNU regex library', conf.env['USE_INCLUDED_REGEX'] and 'built-in' or 'system')
228 conf.msg('Compiling Subversion revision', svn_rev)
232 opt.tool_options('compiler_cc')
233 opt.tool_options('compiler_cxx')
234 opt.tool_options('intltool')
237 opt.add_option('--disable-plugins', action='store_true', default=False,
238 help='compile without plugin support [default: No]', dest='no_plugins')
239 opt.add_option('--disable-socket', action='store_true', default=False,
240 help='compile without support to detect a running instance [[default: No]',
242 opt.add_option('--disable-vte', action='store_true', default=False,
243 help='compile without support for an embedded virtual terminal [[default: No]',
245 opt.add_option('--enable-gnu-regex', action='store_true', default=False,
246 help='compile with included GNU regex library [default: No]', dest='gnu_regex')
248 opt.add_option('--mandir', type='string', default='',
249 help='man documentation', dest='mandir')
250 opt.add_option('--docdir', type='string', default='',
251 help='documentation root', dest='docdir')
252 opt.add_option('--libdir', type='string', default='',
253 help='object code libraries', dest='libdir')
255 opt.add_option('--hackingdoc', action='store_true', default=False,
256 help='generate HTML documentation from HACKING file', dest='hackingdoc')
260 is_win32 = _target_is_win32(bld)
262 if bld.cmd == 'clean':
263 _remove_linguas_file()
264 if bld.cmd in ('install', 'uninstall'):
265 bld.add_post_fun(_post_install)
267 def build_plugin(plugin_name, install=True):
269 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
274 features = ['c', 'cshlib'],
275 source = 'plugins/%s.c' % plugin_name,
276 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/include'],
277 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
278 target = plugin_name,
280 install_path = instpath)
284 if bld.env['USE_INCLUDED_REGEX'] == 1:
285 tagmanager_sources.add('tagmanager/regex.c')
287 features = ['c', 'cstlib'],
288 source = tagmanager_sources,
290 target = 'tagmanager',
291 includes = ['.', 'tagmanager', 'tagmanager/include'],
292 defines = 'G_LOG_DOMAIN="Tagmanager"',
294 install_path = None) # do not install this library
299 features = ['c', 'cstlib'],
300 source = mio_sources,
303 includes = ['.', 'tagmanager/mio/'],
304 defines = 'G_LOG_DOMAIN="MIO"',
306 install_path = None) # do not install this library
310 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
311 scintilla_sources.update(files)
313 features = ['c', 'cxx', 'cxxstlib'],
315 target = 'scintilla',
316 source = scintilla_sources,
317 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
319 install_path = None) # do not install this library
323 if bld.env['HAVE_VTE'] == 1:
324 geany_sources.add('src/vte.c')
326 geany_sources.add('src/win32.c')
327 geany_sources.add('geany_private.rc')
330 features = ['c', 'cxx', 'cprogram'],
333 source = geany_sources,
334 includes = ['.', 'scintilla/include/', 'tagmanager/include/'],
335 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
336 uselib = ['GTK', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
337 use = ['scintilla', 'tagmanager', 'mio'])
341 source = ['plugins/genapi.py', 'src/plugins.c'],
342 name = 'geanyfunctions.h',
343 before = ['c', 'cxx'],
344 cwd = '%s/plugins' % bld.path.abspath(),
345 rule = 'python genapi.py -q')
348 if bld.env['HAVE_PLUGINS'] == 1:
349 build_plugin('classbuilder')
350 build_plugin('demoplugin', False)
351 build_plugin('export')
352 build_plugin('filebrowser')
353 build_plugin('htmlchars')
354 build_plugin('saveactions')
355 build_plugin('splitwindow', not is_win32)
358 if bld.env['INTLTOOL']:
360 features = ['linguas', 'intltool_po'],
362 install_path = '${LOCALEDIR}',
366 task = bld.new_task_gen(
367 source = 'geany.pc.in',
368 dct = {'VERSION' : VERSION,
369 'prefix': bld.env['PREFIX'],
370 'exec_prefix': '${prefix}',
371 'libdir': '${exec_prefix}/lib',
372 'includedir': '${prefix}/include',
373 'datarootdir': '${prefix}/share',
374 'datadir': '${datarootdir}',
375 'localedir': '${datarootdir}/locale'})
379 if bld.env['INTLTOOL']:
381 features = 'intltool_in',
382 source = 'geany.desktop.in',
383 flags = [ '-d', '-q', '-u', '-c' ],
384 install_path = '${DATADIR}/applications')
389 source = 'doc/geany.1.in',
391 dct = {'VERSION' : VERSION,
392 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
393 install_path = '${MANDIR}/man1')
398 source = 'geany.spec.in',
399 target = 'geany.spec',
401 dct = {'VERSION' : VERSION})
406 source = 'doc/Doxyfile.in',
407 target = 'doc/Doxyfile',
409 dct = {'VERSION' : VERSION})
416 bld.install_files('${PREFIX}/include/geany', '''
417 src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
418 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
419 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
420 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h
421 plugins/geanyplugin.h plugins/geanyfunctions.h''')
422 bld.install_files('${PREFIX}/include/geany/scintilla', '''
423 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
424 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
425 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
426 tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
427 tagmanager/include/tm_source_file.h
428 tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
429 tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
430 tagmanager/include/tm_workspace.h ''')
432 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
433 ext = '.txt' if is_win32 else ''
434 html_dir = '' if is_win32 else 'html/'
435 html_name = 'Manual.html' if is_win32 else 'index.html'
436 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
437 basename = _uc_first(filename, bld)
438 destination_filename = '%s%s' % (basename, ext)
439 destination = os.path.join(base_dir, destination_filename)
440 bld.install_as(destination, filename)
442 start_dir = bld.path.find_dir('doc/images')
443 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
444 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
445 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
446 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
448 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
449 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
451 data_dir = '' if is_win32 else 'geany'
452 start_dir = bld.path.find_dir('data')
453 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
454 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
455 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
456 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
457 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
458 start_dir = bld.path.find_dir('data/colorschemes')
459 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
460 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
461 start_dir = bld.path.find_dir('data/templates')
462 template_dest = '${DATADIR}/%s/templates' % data_dir
463 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
465 icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
466 start_dir = bld.path.find_dir('icons/16x16')
467 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
469 start_dir = bld.path.find_dir('icons/48x48')
470 icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
471 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
472 start_dir = bld.path.find_dir('icons/scalable')
473 scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
474 bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
478 Scripting.distclean(ctx)
479 _remove_linguas_file()
482 def _remove_linguas_file():
483 # remove LINGUAS file as well
485 os.unlink(LINGUAS_FILE)
491 def write_linguas_file(self):
492 if os.path.exists(LINGUAS_FILE):
495 if 'LINGUAS' in self.env:
496 files = self.env['LINGUAS']
497 for po_filename in files.split(' '):
498 if os.path.exists ('po/%s.po' % po_filename):
499 linguas += '%s ' % po_filename
501 files = os.listdir('%s/po' % self.path.abspath())
503 for filename in files:
504 if filename.endswith('.po'):
505 linguas += '%s ' % filename[:-3]
506 file_h = open(LINGUAS_FILE, 'w')
507 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
511 def _post_install(ctx):
512 is_win32 = _target_is_win32(ctx)
515 theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
516 icon_cache_updated = False
517 if not ctx.options.destdir:
518 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
519 Logs.pprint('GREEN', 'GTK icon cache updated.')
520 icon_cache_updated = True
521 if not icon_cache_updated:
522 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
523 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
527 """update the message catalogs for internationalization"""
528 potfile = '%s.pot' % APPNAME
529 os.chdir('%s/po' % top)
532 old_size = os.stat(potfile).st_size
535 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
536 size_new = os.stat(potfile).st_size
537 if size_new != old_size:
538 Logs.pprint('CYAN', 'Updated POT file.')
539 Logs.pprint('CYAN', 'Updating translations')
540 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
542 Logs.pprint('RED', 'Updating translations failed')
544 Logs.pprint('CYAN', 'POT file is up to date.')
546 Logs.pprint('RED', 'Failed to generate pot file.')
550 """generate API reference documentation"""
551 basedir = ctx.path.abspath()
552 doxygen = _find_program(ctx, 'doxygen')
553 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
555 Logs.pprint('CYAN', 'Generating API documentation')
556 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
558 raise WafError('Generating API documentation failed')
559 # update hacking.html
560 cmd = _find_rst2html(ctx)
561 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
566 """generate HTML documentation"""
567 # first try rst2html.py as it is the upstream default, fall back to rst2html
568 cmd = _find_rst2html(ctx)
570 Logs.pprint('CYAN', 'Generating HTML documentation')
571 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
575 def _find_program(ctx, cmd, **kw):
579 ctx = ConfigurationContext()
582 return ctx.find_program(cmd, **kw)
585 def _find_rst2html(ctx):
586 cmds = ['rst2html.py', 'rst2html']
588 cmd = _find_program(ctx, command, mandatory=False)
593 'rst2html.py could not be found. Please install the Python docutils package.')
597 def _add_define_to_env(conf, key):
598 value = conf.get_define(key)
600 value = value.replace('"', '')
601 conf.env[key] = value
604 def _add_to_env_and_define(conf, key, value, quote=False):
605 conf.define(key, value, quote)
606 conf.env[key] = value
609 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
610 value = default_value
612 if isinstance(opt_value, bool):
616 if value is not None:
617 _add_to_env_and_define(conf, define_name, value, quote)
619 conf.undefine(define_name)
622 def _get_svn_rev(conf):
624 cmd = 'git ls-files >/dev/null 2>&1'
625 return (conf.exec_command(cmd) == 0)
628 return os.path.exists('.svn')
632 cmds = [ 'git svn find-rev HEAD 2>/dev/null',
633 'git svn find-rev origin/trunk 2>/dev/null',
634 'git svn find-rev trunk 2>/dev/null',
635 'git svn find-rev master 2>/dev/null'
639 stdout = conf.cmd_and_log(cmd)
641 return int(stdout.strip())
645 Logs.pprint('RED', 'Unparseable revision number')
649 _env = None if _target_is_win32(conf) else dict(LANG='C')
650 stdout = conf.cmd_and_log(cmd='svn info --non-interactive', env=_env)
651 lines = stdout.splitlines(True)
653 if line.startswith('Last Changed Rev'):
654 value = line.split(': ', 1)[1]
655 return int(value.strip())
658 except (IndexError, ValueError):
659 Logs.pprint('RED', 'Unparseable revision number')
663 def _load_intltool_if_available(conf):
665 conf.check_tool('intltool')
666 if 'LINGUAS' in os.environ:
667 conf.env['LINGUAS'] = os.environ['LINGUAS']
669 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
670 if not _target_is_win32(conf):
674 def _target_is_win32(ctx):
675 if 'is_win32' in ctx.env:
677 return ctx.env['is_win32']
679 if sys.platform == 'win32':
682 if ctx.env and 'CC' in ctx.env:
683 env_cc = ctx.env['CC']
684 if not isinstance(env_cc, str):
685 env_cc = ''.join(env_cc)
686 is_win32 = (env_cc.find('mingw') != -1)
689 # cache for future checks
690 ctx.env['is_win32'] = is_win32
694 def _uc_first(string, ctx):
695 if _target_is_win32(ctx):
696 return string.title()