Replace doc-comments with '/* *' comments to show there's no build
[geany-mirror.git] / wscript
bloba6dfa5e37d68b0d52c7c7800a463860e38308dc5
1 # -*- coding: utf-8 -*-
3 # WAF build script - this file is part of Geany, a fast and lightweight IDE
5 # Copyright 2008-2010 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
6 # Copyright 2008-2010 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.
22 # $Id$
24 """
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)
31 or at least equally.
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).
41 """
44 import sys
45 import os
46 import tempfile
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
54 APPNAME = 'geany'
55 VERSION = '0.20'
56 LINGUAS_FILE = 'po/LINGUAS'
58 top = '.'
59 out = '_build_'
62 tagmanager_sources = set([
63     'tagmanager/args.c', 'tagmanager/abc.c', 'tagmanager/actionscript.c', 'tagmanager/asm.c',
64     'tagmanager/basic.c', 'tagmanager/c.c',
65     'tagmanager/conf.c', 'tagmanager/css.c', 'tagmanager/ctags.c', 'tagmanager/diff.c',
66     'tagmanager/docbook.c', 'tagmanager/entry.c', 'tagmanager/fortran.c', 'tagmanager/get.c',
67     'tagmanager/haskell.c', 'tagmanager/haxe.c', 'tagmanager/html.c', 'tagmanager/js.c',
68     'tagmanager/keyword.c', 'tagmanager/latex.c', 'tagmanager/lregex.c', 'tagmanager/lua.c',
69     'tagmanager/make.c', 'tagmanager/markdown.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
70     'tagmanager/nestlevel.c', 'tagmanager/options.c',
71     'tagmanager/parse.c', 'tagmanager/pascal.c', 'tagmanager/r.c',
72     'tagmanager/perl.c', 'tagmanager/php.c', 'tagmanager/python.c', 'tagmanager/read.c',
73     'tagmanager/rest.c', 'tagmanager/ruby.c', 'tagmanager/sh.c', 'tagmanager/sort.c',
74     'tagmanager/sql.c', 'tagmanager/strlist.c', 'tagmanager/txt2tags.c', 'tagmanager/tcl.c',
75     'tagmanager/tm_file_entry.c',
76     'tagmanager/tm_project.c', 'tagmanager/tm_source_file.c', 'tagmanager/tm_symbol.c',
77     'tagmanager/tm_tag.c', 'tagmanager/tm_tagmanager.c', 'tagmanager/tm_work_object.c',
78     'tagmanager/tm_workspace.c', 'tagmanager/vhdl.c', 'tagmanager/verilog.c', 'tagmanager/vstring.c'])
80 scintilla_sources = set([
81     'scintilla/AutoComplete.cxx', 'scintilla/CallTip.cxx', 'scintilla/CellBuffer.cxx',
82     'scintilla/CharClassify.cxx', 'scintilla/ContractionState.cxx', 'scintilla/Decoration.cxx',
83     'scintilla/DocumentAccessor.cxx', 'scintilla/Document.cxx', 'scintilla/Editor.cxx',
84     'scintilla/ExternalLexer.cxx',  'scintilla/Indicator.cxx',  'scintilla/KeyMap.cxx',
85     'scintilla/KeyWords.cxx',
86     'scintilla/LexAda.cxx', 'scintilla/LexAsm.cxx', 'scintilla/LexBash.cxx',
87     'scintilla/LexBasic.cxx', 'scintilla/LexCaml.cxx', 'scintilla/LexCmake.cxx', 'scintilla/LexCPP.cxx',
88     'scintilla/LexCSS.cxx', 'scintilla/LexD.cxx', 'scintilla/LexErlang.cxx', 'scintilla/LexForth.cxx',
89     'scintilla/LexFortran.cxx', 'scintilla/LexHaskell.cxx', 'scintilla/LexHTML.cxx', 'scintilla/LexLisp.cxx',
90     'scintilla/LexLua.cxx', 'scintilla/LexMarkdown.cxx', 'scintilla/LexMatlab.cxx',
91     'scintilla/LexNsis.cxx', 'scintilla/LexOthers.cxx',
92     'scintilla/LexPascal.cxx', 'scintilla/LexPerl.cxx', 'scintilla/LexPython.cxx',
93     'scintilla/LexR.cxx', 'scintilla/LexRuby.cxx', 'scintilla/LexSQL.cxx',
94     'scintilla/LexTCL.cxx', 'scintilla/LexTxt2tags.cxx',
95     'scintilla/LexVHDL.cxx', 'scintilla/LexVerilog.cxx', 'scintilla/LexYAML.cxx',
96     'scintilla/LineMarker.cxx', 'scintilla/PerLine.cxx',
97     'scintilla/PlatGTK.cxx',
98     'scintilla/PositionCache.cxx', 'scintilla/PropSet.cxx', 'scintilla/RESearch.cxx',
99     'scintilla/RunStyles.cxx', 'scintilla/ScintillaBase.cxx', 'scintilla/ScintillaGTK.cxx',
100     'scintilla/scintilla-marshal.c', 'scintilla/Selection.cxx', 'scintilla/StyleContext.cxx', 'scintilla/Style.cxx',
101     'scintilla/UniConversion.cxx', 'scintilla/ViewStyle.cxx', 'scintilla/WindowAccessor.cxx',
102     'scintilla/XPM.cxx'])
104 geany_sources = set([
105     'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
106     'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
107     'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
108     'src/highlighting.c', 'src/interface.c', 'src/keybindings.c',
109     'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
110     'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
111     'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
112     'src/symbols.c',
113     'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
114     'src/ui_utils.c', 'src/utils.c'])
118 def configure(conf):
120     conf.check_waf_version(mini='1.6.1')
122     conf.load('compiler_c')
123     is_win32 = _target_is_win32(conf)
125     conf.check_cc(header_name='fcntl.h', mandatory=False)
126     conf.check_cc(header_name='fnmatch.h', mandatory=False)
127     conf.check_cc(header_name='glob.h', mandatory=False)
128     conf.check_cc(header_name='sys/time.h', mandatory=False)
129     conf.check_cc(header_name='sys/types.h', mandatory=False)
130     conf.check_cc(header_name='sys/stat.h', mandatory=False)
131     conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
132     conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
134     if conf.options.gnu_regex:
135         _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
136         _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
137     else:
138         try:
139             conf.check_cc(header_name='regex.h')
140             conf.check_cc(function_name='regcomp', header_name='regex.h')
141         except ConfigurationError:
142             _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1)
143             _add_to_env_and_define(conf, 'USE_INCLUDED_REGEX', 1)
145     conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
146     conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
147     conf.check_cc(function_name='gethostname', header_name='unistd.h', mandatory=False)
148     conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
149     conf.check_cc(function_name='strstr', header_name='string.h')
151     # check sunOS socket support
152     if Options.platform == 'sunos':
153         conf.check_cc(function_name='socket', lib='socket',
154                       header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
156     # check for cxx after the header and function checks have been done to ensure they are
157     # checked with cc not cxx
158     conf.load('compiler_cxx')
159     if is_win32:
160         conf.load('winres')
161     _load_intltool_if_available(conf)
163     # GTK / GIO version check
164     conf.check_cfg(package='gtk+-2.0', atleast_version='2.8.0', uselib_store='GTK',
165         mandatory=True, args='--cflags --libs')
166     have_gtk_210 = False
167     gtk_version = conf.check_cfg(modversion='gtk+-2.0', uselib_store='GTK')
168     if gtk_version:
169         if version.LooseVersion(gtk_version) >= version.LooseVersion('2.10.0'):
170             have_gtk_210 = True
171     else:
172         gtk_version = 'Unknown'
173     conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=False)
175     # Windows specials
176     if is_win32:
177         if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
178             # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
179             new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
180             _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
181             _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
182         _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
183         _add_to_env_and_define(conf, 'LIBDIR', conf.env['PREFIX'], quote=True)
184         conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
185         # overwrite LOCALEDIR to install message catalogues properly
186         conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share/locale')
187         # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
188         conf.undefine('DATADIR')
189         conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
190         conf.env.append_value('LINKFLAGS_cprogram', ['-mwindows'])
191         conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
192     else:
193         conf.env['cshlib_PATTERN'] = '%s.so'
194         # DATADIR and LOCALEDIR are defined by the intltool tool
195         # but they are not added to the environment, so we need to
196         _add_define_to_env(conf, 'DATADIR')
197         _add_define_to_env(conf, 'LOCALEDIR')
198         docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
199         libdir = os.path.join(conf.env['PREFIX'], 'lib')
200         mandir = os.path.join(conf.env['DATADIR'], 'man')
201         _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
202         _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
203         _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
205     svn_rev = _get_svn_rev(conf)
207     conf.define('ENABLE_NLS', 1)
208     conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
209     conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
210     conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
211     conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
212     conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
213     conf.define('PACKAGE', APPNAME, quote=True)
214     conf.define('VERSION', VERSION, quote=True)
215     conf.define('REVISION', str(svn_rev), quote=True)
217     conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
219     # no VTE on Windows
220     if is_win32:
221         conf.options.no_vte = True
223     _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
224     _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
225     _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
227     conf.write_config_header('config.h', remove=False)
229     # some more compiler flags
230     conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
231     if svn_rev > -1:
232         conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
233     # Scintilla flags
234     conf.env.append_value('CFLAGS', ['-DGTK'])
235     conf.env.append_value('CXXFLAGS',
236         ['-DNDEBUG', '-DGTK', '-DGTK2', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
238     # summary
239     Logs.pprint('BLUE', 'Summary:')
240     conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
241     conf.msg('Using GTK version', gtk_version)
242     conf.msg('Build with GTK printing support', have_gtk_210 and 'yes' or 'no')
243     conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
244     conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
245     conf.msg('GNU regex library', conf.env['USE_INCLUDED_REGEX'] and 'built-in' or 'system')
246     if svn_rev > -1:
247         conf.msg('Compiling Subversion revision', svn_rev)
250 def options(opt):
251     opt.tool_options('compiler_cc')
252     opt.tool_options('compiler_cxx')
253     opt.tool_options('intltool')
255     # Features
256     opt.add_option('--disable-plugins', action='store_true', default=False,
257         help='compile without plugin support [default: No]', dest='no_plugins')
258     opt.add_option('--disable-socket', action='store_true', default=False,
259         help='compile without support to detect a running instance [[default: No]',
260         dest='no_socket')
261     opt.add_option('--disable-vte', action='store_true', default=False,
262         help='compile without support for an embedded virtual terminal [[default: No]',
263         dest='no_vte')
264     opt.add_option('--enable-gnu-regex', action='store_true', default=False,
265         help='compile with included GNU regex library [default: No]', dest='gnu_regex')
266     # Paths
267     opt.add_option('--mandir', type='string', default='',
268         help='man documentation', dest='mandir')
269     opt.add_option('--docdir', type='string', default='',
270         help='documentation root', dest='docdir')
271     opt.add_option('--libdir', type='string', default='',
272         help='object code libraries', dest='libdir')
273     # Actions
274     opt.add_option('--hackingdoc', action='store_true', default=False,
275         help='generate HTML documentation from HACKING file', dest='hackingdoc')
278 def build(bld):
279     is_win32 = _target_is_win32(bld)
281     if bld.cmd == 'clean':
282         _remove_linguas_file()
283     if bld.cmd in ('install', 'uninstall'):
284         bld.add_post_fun(_post_install)
286     def build_plugin(plugin_name, install=True):
287         if install:
288             instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
289         else:
290             instpath = None
292         bld.new_task_gen(
293             features                = ['c', 'cshlib'],
294             source                  = 'plugins/%s.c' % plugin_name,
295             includes                = ['.', 'src/', 'scintilla/include', 'tagmanager/include'],
296             defines                 = 'G_LOG_DOMAIN="%s"' % plugin_name,
297             target                  = plugin_name,
298             uselib                  = 'GTK',
299             install_path            = instpath)
302     # Tagmanager
303     if bld.env['USE_INCLUDED_REGEX'] == 1:
304         tagmanager_sources.add('tagmanager/regex.c')
305     bld.new_task_gen(
306         features        = ['c', 'cstlib'],
307         source          = tagmanager_sources,
308         name            = 'tagmanager',
309         target          = 'tagmanager',
310         includes        = ['.', 'tagmanager/include/'],
311         defines         = 'G_LOG_DOMAIN="Tagmanager"',
312         uselib          = 'GTK',
313         install_path    = None) # do not install this library
316     # Scintilla
317     bld.new_task_gen(
318         features        = ['c', 'cxx', 'cxxstlib'],
319         name            = 'scintilla',
320         target          = 'scintilla',
321         source          = scintilla_sources,
322         includes        = ['.', 'scintilla/include/'],
323         uselib          = 'GTK',
324         install_path    = None) # do not install this library
327     # Geany
328     if bld.env['HAVE_VTE'] == 1:
329         geany_sources.add('src/vte.c')
330     if is_win32:
331         geany_sources.add('src/win32.c')
332         geany_sources.add('geany_private.rc')
334     bld.new_task_gen(
335         features        = ['c', 'cxx', 'cprogram'],
336         name            = 'geany',
337         target          = 'geany',
338         source          = geany_sources,
339         includes        = ['.', 'scintilla/include/', 'tagmanager/include/'],
340         defines         = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
341         uselib          = ['GTK', 'GIO', 'WIN32', 'SUNOS_SOCKET'],
342         use             = ['scintilla', 'tagmanager'])
344     # geanyfunctions.h
345     bld.new_task_gen(
346         source  = ['plugins/genapi.py', 'src/plugins.c'],
347         name    = 'geanyfunctions.h',
348         before  = ['c', 'cxx'],
349         cwd     = '%s/plugins' % bld.path.abspath(),
350         rule    = 'python genapi.py -q')
352     # Plugins
353     if bld.env['HAVE_PLUGINS'] == 1:
354         build_plugin('classbuilder')
355         build_plugin('demoplugin', False)
356         build_plugin('export')
357         build_plugin('filebrowser')
358         build_plugin('htmlchars')
359         build_plugin('saveactions')
360         build_plugin('splitwindow', not is_win32)
362     # Translations
363     if bld.env['INTLTOOL']:
364         bld.new_task_gen(
365             features        = ['linguas', 'intltool_po'],
366             podir           = 'po',
367             install_path    = '${LOCALEDIR}',
368             appname         = 'geany')
370     # geany.pc
371     task = bld.new_task_gen(
372         source          = 'geany.pc.in',
373         dct             = {'VERSION' : VERSION,
374                            'prefix': bld.env['PREFIX'],
375                            'exec_prefix': '${prefix}',
376                            'libdir': '${exec_prefix}/lib',
377                            'includedir': '${prefix}/include',
378                            'datarootdir': '${prefix}/share',
379                            'datadir': '${datarootdir}',
380                            'localedir': '${datarootdir}/locale'})
382     if not is_win32:
383         # geany.desktop
384         if bld.env['INTLTOOL']:
385             bld.new_task_gen(
386                 features        = 'intltool_in',
387                 source          = 'geany.desktop.in',
388                 flags           = [ '-d', '-q', '-u', '-c' ],
389                 install_path    = '${DATADIR}/applications')
391         # geany.1
392         bld.new_task_gen(
393             features        = 'subst',
394             source          = 'doc/geany.1.in',
395             target          = 'geany.1',
396             dct             = {'VERSION' : VERSION,
397                                 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
398             install_path    = '${MANDIR}/man1')
400         # geany.spec
401         bld.new_task_gen(
402             features        = 'subst',
403             source          = 'geany.spec.in',
404             target          = 'geany.spec',
405             install_path    = None,
406             dct             = {'VERSION' : VERSION})
408         # Doxyfile
409         bld.new_task_gen(
410             features        = 'subst',
411             source          = 'doc/Doxyfile.in',
412             target          = 'doc/Doxyfile',
413             install_path    = None,
414             dct             = {'VERSION' : VERSION})
416     ###
417     # Install files
418     ###
419     if not is_win32:
420         # Headers
421         bld.install_files('${PREFIX}/include/geany', '''
422             src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
423             src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
424             src/prefs.h src/project.h src/search.h src/stash.h src/support.h
425             src/templates.h src/toolbar.h src/ui_utils.h src/utils.h
426             plugins/geanyplugin.h plugins/geanyfunctions.h''')
427         bld.install_files('${PREFIX}/include/geany/scintilla', '''
428             scintilla/include/SciLexer.h scintilla/include/Scintilla.h
429             scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
430         bld.install_files('${PREFIX}/include/geany/tagmanager', '''
431             tagmanager/include/tm_file_entry.h tagmanager/include/tm_project.h
432             tagmanager/include/tm_source_file.h
433             tagmanager/include/tm_symbol.h tagmanager/include/tm_tag.h
434             tagmanager/include/tm_tagmanager.h tagmanager/include/tm_work_object.h
435             tagmanager/include/tm_workspace.h ''')
436     # Docs
437     base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
438     ext = '.txt' if is_win32 else ''
439     html_dir = '' if is_win32 else 'html/'
440     html_name = 'Manual.html' if is_win32 else 'index.html'
441     for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
442         basename = _uc_first(filename, bld)
443         destination_filename = '%s%s' % (basename, ext)
444         destination = os.path.join(base_dir, destination_filename)
445         bld.install_as(destination, filename)
447     start_dir = bld.path.find_dir('doc/images')
448     bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
449     bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
450     bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
451     bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
452     if is_win32:
453         bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
454         bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
455     # Data
456     data_dir = '' if is_win32 else 'geany'
457     start_dir = bld.path.find_dir('data')
458     bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
459     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
460     bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
461     bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
462     bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
463     start_dir = bld.path.find_dir('data/colorschemes')
464     template_dest = '${DATADIR}/%s/colorschemes' % data_dir
465     bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
466     start_dir = bld.path.find_dir('data/templates')
467     template_dest = '${DATADIR}/%s/templates' % data_dir
468     bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
469     # Icons
470     icon_dest = '${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons/hicolor/16x16/apps'
471     start_dir = bld.path.find_dir('icons/16x16')
472     bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
473     if not is_win32:
474         start_dir = bld.path.find_dir('icons/48x48')
475         icon_dest = '${DATADIR}/icons/hicolor/48x48/apps'
476         bld.install_files(icon_dest, start_dir.ant_glob('*.png'), cwd=start_dir)
477         start_dir = bld.path.find_dir('icons/scalable')
478         scalable_dest = '${DATADIR}/icons/hicolor/scalable/apps'
479         bld.install_files(scalable_dest, start_dir.ant_glob('*.svg'), cwd=start_dir)
482 def distclean(ctx):
483     Scripting.distclean(ctx)
484     _remove_linguas_file()
487 def _remove_linguas_file():
488     # remove LINGUAS file as well
489     try:
490         os.unlink(LINGUAS_FILE)
491     except OSError:
492         pass
495 @feature('linguas')
496 def write_linguas_file(self):
497     if os.path.exists(LINGUAS_FILE):
498         return
499     linguas = ''
500     if 'LINGUAS' in self.env:
501         files = self.env['LINGUAS']
502         for po_filename in files.split(' '):
503             if os.path.exists ('po/%s.po' % po_filename):
504                 linguas += '%s ' % po_filename
505     else:
506         files = os.listdir('%s/po' % self.path.abspath())
507         files.sort()
508         for filename in files:
509             if filename.endswith('.po'):
510                 linguas += '%s ' % filename[:-3]
511     file_h = open(LINGUAS_FILE, 'w')
512     file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
513     file_h.close()
516 def _post_install(ctx):
517     is_win32 = _target_is_win32(ctx)
518     if is_win32:
519         return
520     theme_dir = Utils.subst_vars('${DATADIR}/icons/hicolor', ctx.env)
521     icon_cache_updated = False
522     if not ctx.options.destdir:
523         ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
524         Logs.pprint('GREEN', 'GTK icon cache updated.')
525         icon_cache_updated = True
526     if not icon_cache_updated:
527         Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
528         Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
531 def updatepo(ctx):
532     """update the message catalogs for internationalization"""
533     potfile = '%s.pot' % APPNAME
534     os.chdir('%s/po' % top)
535     try:
536         try:
537             old_size = os.stat(potfile).st_size
538         except OSError:
539             old_size = 0
540         ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
541         size_new = os.stat(potfile).st_size
542         if size_new != old_size:
543             Logs.pprint('CYAN', 'Updated POT file.')
544             Logs.pprint('CYAN', 'Updating translations')
545             ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
546             if ret != 0:
547                 Logs.pprint('RED', 'Updating translations failed')
548         else:
549             Logs.pprint('CYAN', 'POT file is up to date.')
550     except OSError:
551         Logs.pprint('RED', 'Failed to generate pot file.')
554 def apidoc(ctx):
555     """generate API reference documentation"""
556     basedir = ctx.path.abspath()
557     doxygen = _find_program(ctx, 'doxygen')
558     doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
559     os.chdir('doc')
560     Logs.pprint('CYAN', 'Generating API documentation')
561     ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
562     if ret != 0:
563         raise WafError('Generating API documentation failed')
564     # update hacking.html
565     cmd = _find_rst2html(ctx)
566     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
567     os.chdir('..')
570 def htmldoc(ctx):
571     """generate HTML documentation"""
572     # first try rst2html.py as it is the upstream default, fall back to rst2html
573     cmd = _find_rst2html(ctx)
574     os.chdir('doc')
575     Logs.pprint('CYAN', 'Generating HTML documentation')
576     ctx.exec_command('%s  -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
577     os.chdir('..')
580 def _find_program(ctx, cmd, **kw):
581     def noop(*args):
582         pass
584     ctx = ConfigurationContext()
585     ctx.to_log = noop
586     ctx.msg = noop
587     return ctx.find_program(cmd, **kw)
590 def _find_rst2html(ctx):
591     cmds = ['rst2html.py', 'rst2html']
592     for command in cmds:
593         cmd = _find_program(ctx, command, mandatory=False)
594         if cmd:
595             break
596     if not cmd:
597         raise WafError(
598             'rst2html.py could not be found. Please install the Python docutils package.')
599     return cmd
602 def _add_define_to_env(conf, key):
603     value = conf.get_define(key)
604     # strip quotes
605     value = value.replace('"', '')
606     conf.env[key] = value
609 def _add_to_env_and_define(conf, key, value, quote=False):
610     conf.define(key, value, quote)
611     conf.env[key] = value
614 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
615     value = default_value
616     if opt_value:
617         if isinstance(opt_value, bool):
618             opt_value = 1
619         value = opt_value
621     if value is not None:
622         _add_to_env_and_define(conf, define_name, value, quote)
623     else:
624         conf.undefine(define_name)
627 def _get_svn_rev(conf):
628     def in_git():
629         cmd = 'git ls-files >/dev/null 2>&1'
630         return (conf.exec_command(cmd) == 0)
632     def in_svn():
633         return os.path.exists('.svn')
635     # try GIT
636     if in_git():
637         cmds = [ 'git svn find-rev HEAD 2>/dev/null',
638                  'git svn find-rev origin/trunk 2>/dev/null',
639                  'git svn find-rev trunk 2>/dev/null',
640                  'git svn find-rev master 2>/dev/null'
641                 ]
642         for cmd in cmds:
643             try:
644                 stdout = conf.cmd_and_log(cmd)
645                 if stdout:
646                     return int(stdout.strip())
647             except WafError:
648                 pass
649             except ValueError:
650                 Logs.pprint('RED', 'Unparseable revision number')
651     # try SVN
652     elif in_svn():
653         try:
654             _env = None if _target_is_win32(conf) else dict(LANG='C')
655             stdout = conf.cmd_and_log(cmd='svn info --non-interactive', env=_env)
656             lines = stdout.splitlines(True)
657             for line in lines:
658                 if line.startswith('Last Changed Rev'):
659                     value = line.split(': ', 1)[1]
660                     return int(value.strip())
661         except WafError:
662             pass
663         except (IndexError, ValueError):
664             Logs.pprint('RED', 'Unparseable revision number')
665     return 0
668 def _load_intltool_if_available(conf):
669     try:
670         conf.check_tool('intltool')
671         if 'LINGUAS' in os.environ:
672             conf.env['LINGUAS'] = os.environ['LINGUAS']
673     except WafError:
674         # on Windows, we don't hard depend on intltool, on all other platforms raise an error
675         if not _target_is_win32(conf):
676             raise
679 def _target_is_win32(ctx):
680     if 'is_win32' in ctx.env:
681         # cached
682         return ctx.env['is_win32']
683     is_win32 = None
684     if sys.platform == 'win32':
685         is_win32 = True
686     if is_win32 is None:
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)
692     if is_win32 is None:
693         is_win32 = False
694     # cache for future checks
695     ctx.env['is_win32'] = is_win32
696     return is_win32
699 def _uc_first(string, ctx):
700     if _target_is_win32(ctx):
701         return string.title()
702     return string