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 ;-)
110 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
112 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
113 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
114 conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
115 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
116 conf.check_cc(function_name='strstr', header_name='string.h')
118 # check sunOS socket support
119 if Options.platform == 'sunos':
120 conf.check_cc(function_name='socket', lib='socket',
121 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
123 # check for cxx after the header and function checks have been done to ensure they are
124 # checked with cc not cxx
125 conf.load('compiler_cxx')
128 _load_intltool_if_available(conf)
130 # GTK / GIO version check
131 conf.check_cfg(package='gtk+-2.0', atleast_version='2.16.0', uselib_store='GTK',
132 mandatory=True, args='--cflags --libs')
133 conf.check_cfg(package='glib-2.0', atleast_version='2.20.0', uselib_store='GLIB',
134 mandatory=True, args='--cflags --libs')
135 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
136 gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK') or 'Unknown'
137 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
141 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
142 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
143 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
144 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
145 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
146 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
147 _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
148 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
149 # overwrite LOCALEDIR to install message catalogues properly
150 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
151 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
152 conf.undefine('DATADIR')
153 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
154 conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
155 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
157 conf.env['cshlib_PATTERN'] = '%s.so'
158 # DATADIR and LOCALEDIR are defined by the intltool tool
159 # but they are not added to the environment, so we need to
160 _add_define_to_env(conf, 'DATADIR')
161 _add_define_to_env(conf, 'LOCALEDIR')
162 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
163 libdir = os.path.join(conf.env['PREFIX'], 'lib')
164 mandir = os.path.join(conf.env['DATADIR'], 'man')
165 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
166 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
167 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
169 revision = _get_git_rev(conf)
171 conf.define('ENABLE_NLS', 1)
172 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
173 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
174 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
175 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
176 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
177 conf.define('PACKAGE', APPNAME, quote=True)
178 conf.define('VERSION', VERSION, quote=True)
179 conf.define('REVISION', revision or '-1', quote=True)
181 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
185 conf.options.no_vte = True
187 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
188 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
189 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
191 conf.write_config_header('config.h', remove=False)
193 # some more compiler flags
194 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
195 if revision is not None:
196 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
198 conf.env.append_value('CFLAGS', ['-DGTK'])
199 conf.env.append_value('CXXFLAGS',
200 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
203 Logs.pprint('BLUE', 'Summary:')
204 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
205 conf.msg('Using GTK version', gtk_version)
206 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
207 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
208 if revision is not None:
209 conf.msg('Compiling Git revision', revision)
213 opt.tool_options('compiler_cc')
214 opt.tool_options('compiler_cxx')
215 opt.tool_options('intltool')
218 opt.add_option('--disable-plugins', action='store_true', default=False,
219 help='compile without plugin support [default: No]', dest='no_plugins')
220 opt.add_option('--disable-socket', action='store_true', default=False,
221 help='compile without support to detect a running instance [[default: No]',
223 opt.add_option('--disable-vte', action='store_true', default=False,
224 help='compile without support for an embedded virtual terminal [[default: No]',
227 opt.add_option('--mandir', type='string', default='',
228 help='man documentation', dest='mandir')
229 opt.add_option('--docdir', type='string', default='',
230 help='documentation root', dest='docdir')
231 opt.add_option('--libdir', type='string', default='',
232 help='object code libraries', dest='libdir')
234 opt.add_option('--hackingdoc', action='store_true', default=False,
235 help='generate HTML documentation from HACKING file', dest='hackingdoc')
239 is_win32 = _target_is_win32(bld)
241 if bld.cmd == 'clean':
242 _remove_linguas_file()
243 if bld.cmd in ('install', 'uninstall'):
244 bld.add_post_fun(_post_install)
246 def build_plugin(plugin_name, install=True):
248 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
253 features = ['c', 'cshlib'],
254 source = 'plugins/%s.c' % plugin_name,
255 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/include'],
256 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
257 target = plugin_name,
258 uselib = ['GTK', 'GLIB'],
259 install_path = instpath)
264 features = ['c', 'cstlib'],
265 source = tagmanager_sources,
267 target = 'tagmanager',
268 includes = ['.', 'tagmanager', 'tagmanager/include'],
269 defines = 'G_LOG_DOMAIN="Tagmanager"',
270 uselib = ['GTK', 'GLIB'],
271 install_path = None) # do not install this library
276 features = ['c', 'cstlib'],
277 source = mio_sources,
280 includes = ['.', 'tagmanager/mio/'],
281 defines = 'G_LOG_DOMAIN="MIO"',
282 uselib = ['GTK', 'GLIB'],
283 install_path = None) # do not install this library
287 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
288 scintilla_sources.update(files)
290 features = ['c', 'cxx', 'cxxstlib'],
292 target = 'scintilla',
293 source = scintilla_sources,
294 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
296 install_path = None) # do not install this library
300 if bld.env['HAVE_VTE'] == 1:
301 geany_sources.add('src/vte.c')
303 geany_sources.add('src/win32.c')
304 geany_sources.add('geany_private.rc')
307 features = ['c', 'cxx', 'cprogram'],
310 source = geany_sources,
311 includes = ['.', 'scintilla/include/', 'tagmanager/include/'],
312 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
313 linkflags = ['-Wl,--export-dynamic'],
314 uselib = ['GTK', 'GLIB', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET'],
315 use = ['scintilla', 'tagmanager', 'mio'])
319 source = ['plugins/genapi.py', 'src/plugins.c'],
320 name = 'geanyfunctions.h',
321 before = ['c', 'cxx'],
322 cwd = '%s/plugins' % bld.path.abspath(),
323 rule = 'python genapi.py -q')
326 if bld.env['HAVE_PLUGINS'] == 1:
327 build_plugin('classbuilder')
328 build_plugin('demoplugin', False)
329 build_plugin('export')
330 build_plugin('filebrowser')
331 build_plugin('htmlchars')
332 build_plugin('saveactions')
333 build_plugin('splitwindow')
336 if bld.env['INTLTOOL']:
338 features = ['linguas', 'intltool_po'],
340 install_path = '${LOCALEDIR}',
345 source = 'geany.pc.in',
346 dct = {'VERSION' : VERSION,
347 'prefix': bld.env['PREFIX'],
348 'exec_prefix': '${prefix}',
349 'libdir': '${exec_prefix}/lib',
350 'includedir': '${prefix}/include',
351 'datarootdir': '${prefix}/share',
352 'datadir': '${datarootdir}',
353 'localedir': '${datarootdir}/locale'})
357 if bld.env['INTLTOOL']:
359 features = 'intltool_in',
360 source = 'geany.desktop.in',
361 flags = [ '-d', '-q', '-u', '-c' ],
362 install_path = '${DATADIR}/applications')
367 source = 'doc/geany.1.in',
369 dct = {'VERSION' : VERSION,
370 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
371 install_path = '${MANDIR}/man1')
376 source = 'geany.spec.in',
377 target = 'geany.spec',
379 dct = {'VERSION' : VERSION})
384 source = 'doc/Doxyfile.in',
385 target = 'doc/Doxyfile',
387 dct = {'VERSION' : VERSION})
394 bld.install_files('${PREFIX}/include/geany', '''
395 src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
396 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
397 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
398 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h
399 plugins/geanyplugin.h plugins/geanyfunctions.h''')
400 bld.install_files('${PREFIX}/include/geany/scintilla', '''
401 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
402 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
403 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
404 tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
405 tagmanager/include/tm_source_file.h
406 tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
407 tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
408 tagmanager/include/tm_workspace.h ''')
410 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
411 ext = '.txt' if is_win32 else ''
412 html_dir = '' if is_win32 else 'html/'
413 html_name = 'Manual.html' if is_win32 else 'index.html'
414 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
415 basename = _uc_first(filename, bld)
416 destination_filename = '%s%s' % (basename, ext)
417 destination = os.path.join(base_dir, destination_filename)
418 bld.install_as(destination, filename)
420 start_dir = bld.path.find_dir('doc/images')
421 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
422 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
423 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
424 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
426 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
427 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
429 data_dir = '' if is_win32 else 'geany'
430 start_dir = bld.path.find_dir('data')
431 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
432 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
433 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
434 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
435 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
436 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
437 start_dir = bld.path.find_dir('data/colorschemes')
438 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
439 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
440 start_dir = bld.path.find_dir('data/templates')
441 template_dest = '${DATADIR}/%s/templates' % data_dir
442 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
444 icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
445 start_dir = bld.path.find_dir('icons/16x16')
446 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
448 start_dir = bld.path.find_dir('icons/48x48')
449 icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
450 bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
451 start_dir = bld.path.find_dir('icons/scalable')
452 scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
453 bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
457 Scripting.distclean(ctx)
458 _remove_linguas_file()
461 def _remove_linguas_file():
462 # remove LINGUAS file as well
464 os.unlink(LINGUAS_FILE)
470 def write_linguas_file(self):
471 if os.path.exists(LINGUAS_FILE):
474 if 'LINGUAS' in self.env:
475 files = self.env['LINGUAS']
476 for po_filename in files.split(' '):
477 if os.path.exists ('po/%s.po' % po_filename):
478 linguas += '%s ' % po_filename
480 files = os.listdir('%s/po' % self.path.abspath())
482 for filename in files:
483 if filename.endswith('.po'):
484 linguas += '%s ' % filename[:-3]
485 file_h = open(LINGUAS_FILE, 'w')
486 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
490 def _post_install(ctx):
491 is_win32 = _target_is_win32(ctx)
494 theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
495 icon_cache_updated = False
496 if not ctx.options.destdir:
497 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
498 Logs.pprint('GREEN', 'GTK icon cache updated.')
499 icon_cache_updated = True
500 if not icon_cache_updated:
501 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
502 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
506 """update the message catalogs for internationalization"""
507 potfile = '%s.pot' % APPNAME
508 os.chdir('%s/po' % top)
511 old_size = os.stat(potfile).st_size
514 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
515 size_new = os.stat(potfile).st_size
516 if size_new != old_size:
517 Logs.pprint('CYAN', 'Updated POT file.')
518 Logs.pprint('CYAN', 'Updating translations')
519 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
521 Logs.pprint('RED', 'Updating translations failed')
523 Logs.pprint('CYAN', 'POT file is up to date.')
525 Logs.pprint('RED', 'Failed to generate pot file.')
529 """generate API reference documentation"""
530 basedir = ctx.path.abspath()
531 doxygen = _find_program(ctx, 'doxygen')
532 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
534 Logs.pprint('CYAN', 'Generating API documentation')
535 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
537 raise WafError('Generating API documentation failed')
538 # update hacking.html
539 cmd = _find_rst2html(ctx)
540 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
545 """generate HTML documentation"""
546 # first try rst2html.py as it is the upstream default, fall back to rst2html
547 cmd = _find_rst2html(ctx)
549 Logs.pprint('CYAN', 'Generating HTML documentation')
550 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
554 def _find_program(ctx, cmd, **kw):
558 ctx = ConfigurationContext()
561 return ctx.find_program(cmd, **kw)
564 def _find_rst2html(ctx):
565 cmds = ['rst2html.py', 'rst2html']
567 cmd = _find_program(ctx, command, mandatory=False)
572 'rst2html.py could not be found. Please install the Python docutils package.')
576 def _add_define_to_env(conf, key):
577 value = conf.get_define(key)
579 value = value.replace('"', '')
580 conf.env[key] = value
583 def _add_to_env_and_define(conf, key, value, quote=False):
584 conf.define(key, value, quote)
585 conf.env[key] = value
588 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
589 value = default_value
591 if isinstance(opt_value, bool):
595 if value is not None:
596 _add_to_env_and_define(conf, define_name, value, quote)
598 conf.undefine(define_name)
601 def _get_git_rev(conf):
602 if not os.path.isdir('.git'):
606 cmd = 'git rev-parse --short --revs-only HEAD'
607 revision = conf.cmd_and_log(cmd).strip()
614 def _load_intltool_if_available(conf):
616 conf.check_tool('intltool')
617 if 'LINGUAS' in os.environ:
618 conf.env['LINGUAS'] = os.environ['LINGUAS']
620 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
621 if not _target_is_win32(conf):
625 def _target_is_win32(ctx):
626 if 'is_win32' in ctx.env:
628 return ctx.env['is_win32']
630 if sys.platform == 'win32':
633 if ctx.env and 'CC' in ctx.env:
634 env_cc = ctx.env['CC']
635 if not isinstance(env_cc, str):
636 env_cc = ''.join(env_cc)
637 is_win32 = (env_cc.find('mingw') != -1)
640 # cache for future checks
641 ctx.env['is_win32'] = is_win32
645 def _uc_first(string, ctx):
646 if _target_is_win32(ctx):
647 return string.title()