1 # -*- coding: utf-8 -*-
3 # WAF build script - this file is part of Geany, a fast and lightweight IDE
5 # Copyright 2008-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
6 # Copyright 2008-2012 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 WafError
48 from waflib.TaskGen import feature, before_method
49 from waflib.Tools.compiler_c import c_compiler
50 from waflib.Tools.compiler_cxx import cxx_compiler
55 LINGUAS_FILE = os.path.join('po', 'LINGUAS')
56 MINIMUM_GTK_VERSION = '2.16.0'
57 MINIMUM_GTK3_VERSION = '3.0.0'
58 MINIMUM_GLIB_VERSION = '2.20.0'
64 mio_sources = set(['tagmanager/mio/mio.c'])
67 'tagmanager/ctags/abaqus.c',
68 'tagmanager/ctags/args.c',
69 'tagmanager/ctags/abc.c',
70 'tagmanager/ctags/actionscript.c',
71 'tagmanager/ctags/asciidoc.c',
72 'tagmanager/ctags/asm.c',
73 'tagmanager/ctags/basic.c',
74 'tagmanager/ctags/c.c',
75 'tagmanager/ctags/cobol.c',
76 'tagmanager/ctags/conf.c',
77 'tagmanager/ctags/css.c',
78 'tagmanager/ctags/ctags.c',
79 'tagmanager/ctags/diff.c',
80 'tagmanager/ctags/docbook.c',
81 'tagmanager/ctags/entry.c',
82 'tagmanager/ctags/fortran.c',
83 'tagmanager/ctags/get.c',
84 'tagmanager/ctags/haskell.c',
85 'tagmanager/ctags/haxe.c',
86 'tagmanager/ctags/html.c',
87 'tagmanager/ctags/js.c',
88 'tagmanager/ctags/keyword.c',
89 'tagmanager/ctags/latex.c',
90 'tagmanager/ctags/lregex.c',
91 'tagmanager/ctags/lua.c',
92 'tagmanager/ctags/make.c',
93 'tagmanager/ctags/markdown.c',
94 'tagmanager/ctags/matlab.c',
95 'tagmanager/ctags/nsis.c',
96 'tagmanager/ctags/nestlevel.c',
97 'tagmanager/ctags/objc.c',
98 'tagmanager/ctags/options.c',
99 'tagmanager/ctags/parse.c',
100 'tagmanager/ctags/pascal.c',
101 'tagmanager/ctags/r.c',
102 'tagmanager/ctags/perl.c',
103 'tagmanager/ctags/php.c',
104 'tagmanager/ctags/python.c',
105 'tagmanager/ctags/read.c',
106 'tagmanager/ctags/rest.c',
107 'tagmanager/ctags/ruby.c',
108 'tagmanager/ctags/rust.c',
109 'tagmanager/ctags/sh.c',
110 'tagmanager/ctags/sort.c',
111 'tagmanager/ctags/sql.c',
112 'tagmanager/ctags/strlist.c',
113 'tagmanager/ctags/txt2tags.c',
114 'tagmanager/ctags/tcl.c',
115 'tagmanager/ctags/vhdl.c',
116 'tagmanager/ctags/verilog.c',
117 'tagmanager/ctags/vstring.c'])
119 tagmanager_sources = set([
120 'tagmanager/src/tm_file_entry.c',
121 'tagmanager/src/tm_project.c',
122 'tagmanager/src/tm_source_file.c',
123 'tagmanager/src/tm_symbol.c',
124 'tagmanager/src/tm_tag.c',
125 'tagmanager/src/tm_tagmanager.c',
126 'tagmanager/src/tm_work_object.c',
127 'tagmanager/src/tm_workspace.c'])
129 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
131 geany_sources = set([
132 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
133 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
134 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
135 'src/highlighting.c', 'src/keybindings.c',
136 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
137 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
138 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
140 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
141 'src/ui_utils.c', 'src/utils.c'])
144 'hicolor/16x16/apps': ['16x16/classviewer-class.png',
145 '16x16/classviewer-macro.png',
146 '16x16/classviewer-member.png',
147 '16x16/classviewer-method.png',
148 '16x16/classviewer-namespace.png',
149 '16x16/classviewer-other.png',
150 '16x16/classviewer-struct.png',
151 '16x16/classviewer-var.png',
153 'hicolor/16x16/actions': ['16x16/geany-build.png',
154 '16x16/geany-close-all.png',
155 '16x16/geany-save-all.png'],
156 'hicolor/24x24/actions': ['24x24/geany-build.png',
157 '24x24/geany-close-all.png',
158 '24x24/geany-save-all.png'],
159 'hicolor/32x32/actions': ['32x32/geany-build.png',
160 '32x32/geany-close-all.png',
161 '32x32/geany-save-all.png'],
162 'hicolor/48x48/actions': ['48x48/geany-build.png',
163 '48x48/geany-close-all.png',
164 '48x48/geany-save-all.png'],
165 'hicolor/48x48/apps': ['48x48/geany.png'],
166 'hicolor/scalable/apps': ['scalable/geany.svg'],
167 'hicolor/scalable/actions': ['scalable/geany-build.svg',
168 'scalable/geany-close-all.svg',
169 'scalable/geany-save-all.svg'],
170 'Tango/16x16/actions': ['tango/16x16/geany-save-all.png'],
171 'Tango/24x24/actions': ['tango/24x24/geany-save-all.png'],
172 'Tango/32x32/actions': ['tango/32x32/geany-save-all.png'],
173 'Tango/48x48/actions': ['tango/48x48/geany-save-all.png'],
174 'Tango/scalable/actions': ['tango/scalable/geany-save-all.svg']
176 geany_icons_indexes = {
177 'hicolor': ['index.theme'],
178 'Tango': ['tango/index.theme']
184 conf.check_waf_version(mini='1.6.1')
186 conf.load('compiler_c')
187 is_win32 = _target_is_win32(conf)
189 conf.check_cc(header_name='fcntl.h', mandatory=False)
190 conf.check_cc(header_name='fnmatch.h', mandatory=False)
191 conf.check_cc(header_name='glob.h', mandatory=False)
192 conf.check_cc(header_name='sys/time.h', mandatory=False)
193 conf.check_cc(header_name='sys/types.h', mandatory=False)
194 conf.check_cc(header_name='sys/stat.h', mandatory=False)
195 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
196 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
197 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
199 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
200 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
201 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
202 conf.check_cc(function_name='strstr', header_name='string.h')
204 conf.check_cc(function_name='pow', header_name='math.h', lib='m', uselib_store='M')
206 # check sunOS socket support
207 if Options.platform == 'sunos':
208 conf.check_cc(function_name='socket', lib='socket',
209 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
211 # check for cxx after the header and function checks have been done to ensure they are
212 # checked with cc not cxx
213 conf.load('compiler_cxx')
216 _load_intltool_if_available(conf)
218 # GTK / GIO version check
219 gtk_package_name = 'gtk+-3.0' if conf.options.use_gtk3 else 'gtk+-2.0'
220 minimum_gtk_version = MINIMUM_GTK3_VERSION if conf.options.use_gtk3 else MINIMUM_GTK_VERSION
221 conf.check_cfg(package=gtk_package_name, atleast_version=minimum_gtk_version, uselib_store='GTK',
222 mandatory=True, args='--cflags --libs')
223 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
224 mandatory=True, args='--cflags --libs')
225 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
226 mandatory=True, args='--cflags --libs')
227 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
228 gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
229 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
230 # remember GTK version for the build step
231 conf.env['gtk_package_name'] = gtk_package_name
232 conf.env['minimum_gtk_version'] = minimum_gtk_version
233 conf.env['use_gtk3'] = conf.options.use_gtk3
237 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
238 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
239 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
240 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
241 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
242 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
243 _add_to_env_and_define(conf, 'LIBDIR', '%s/lib' % conf.env['PREFIX'], quote=True)
244 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
245 # overwrite LOCALEDIR to install message catalogues properly
246 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share', 'locale')
247 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
248 conf.undefine('DATADIR')
249 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
250 conf.env.append_value('LINKFLAGS_cprogram', [
253 '-static-libstdc++'])
254 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
256 conf.env['cshlib_PATTERN'] = '%s.so'
257 # DATADIR and LOCALEDIR are defined by the intltool tool
258 # but they are not added to the environment, so we need to
259 _add_define_to_env(conf, 'DATADIR')
260 _add_define_to_env(conf, 'LOCALEDIR')
261 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
262 libdir = os.path.join(conf.env['PREFIX'], 'lib')
263 mandir = os.path.join(conf.env['DATADIR'], 'man')
264 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
265 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
266 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
268 revision = _get_git_rev(conf)
270 conf.define('ENABLE_NLS', 1)
271 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
272 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
273 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
274 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
275 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
276 conf.define('PACKAGE', APPNAME, quote=True)
277 conf.define('VERSION', VERSION, quote=True)
278 conf.define('REVISION', revision or '-1', quote=True)
280 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
284 conf.options.no_vte = True
286 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
287 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
288 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
290 conf.write_config_header('config.h', remove=False)
292 # some more compiler flags
293 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
294 if revision is not None:
295 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
297 conf.env.append_value('CFLAGS', ['-DGTK'])
298 conf.env.append_value('CXXFLAGS',
299 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
302 Logs.pprint('BLUE', 'Summary:')
303 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
304 conf.msg('Using GTK version', gtk_version)
305 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
306 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
307 if revision is not None:
308 conf.msg('Compiling Git revision', revision)
312 # Disable MSVC detection on win32: building Geany with MSVC is currently not supported
313 # If anyone wants to add support for building with MSVC, this hack should be removed.
314 c_compiler['win32'] = ['gcc']
315 cxx_compiler['win32'] = ['g++']
317 opt.load('compiler_cc')
318 opt.load('compiler_cxx')
322 opt.add_option('--no-scm', action='store_true', default=False,
323 help='Disable SCM detection [default: No]', dest='no_scm')
325 opt.add_option('--disable-plugins', action='store_true', default=False,
326 help='compile without plugin support [default: No]', dest='no_plugins')
327 opt.add_option('--disable-socket', action='store_true', default=False,
328 help='compile without support to detect a running instance [[default: No]',
330 opt.add_option('--disable-vte', action='store_true', default=False,
331 help='compile without support for an embedded virtual terminal [[default: No]',
333 opt.add_option('--enable-gtk3', action='store_true', default=False,
334 help='compile with GTK3 support (experimental) [[default: No]',
337 opt.add_option('--mandir', type='string', default='',
338 help='man documentation', dest='mandir')
339 opt.add_option('--docdir', type='string', default='',
340 help='documentation root', dest='docdir')
341 opt.add_option('--libdir', type='string', default='',
342 help='object code libraries', dest='libdir')
344 opt.add_option('--hackingdoc', action='store_true', default=False,
345 help='generate HTML documentation from HACKING file', dest='hackingdoc')
349 is_win32 = _target_is_win32(bld)
351 if bld.cmd == 'clean':
352 _remove_linguas_file()
353 if bld.cmd in ('install', 'uninstall'):
354 bld.add_post_fun(_post_install)
356 def build_plugin(plugin_name, install=True, uselib_add=[]):
358 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
363 features = ['c', 'cshlib'],
364 source = 'plugins/%s.c' % plugin_name,
365 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
366 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
367 target = plugin_name,
368 uselib = ['GTK', 'GLIB', 'GMODULE'] + uselib_add,
369 install_path = instpath)
373 features = ['c', 'cstlib'],
374 source = ctags_sources,
377 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
378 defines = 'G_LOG_DOMAIN="CTags"',
380 install_path = None) # do not install this library
384 features = ['c', 'cstlib'],
385 source = tagmanager_sources,
387 target = 'tagmanager',
388 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
389 defines = 'G_LOG_DOMAIN="Tagmanager"',
390 uselib = ['GTK', 'GLIB'],
391 install_path = None) # do not install this library
395 features = ['c', 'cstlib'],
396 source = mio_sources,
399 includes = ['.', 'tagmanager/mio/'],
400 defines = 'G_LOG_DOMAIN="MIO"',
401 uselib = ['GTK', 'GLIB'],
402 install_path = None) # do not install this library
405 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
406 scintilla_sources.update(files)
408 features = ['c', 'cxx', 'cxxstlib'],
410 target = 'scintilla',
411 source = scintilla_sources,
412 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
413 uselib = ['GTK', 'GLIB', 'GMODULE', 'M'],
414 install_path = None) # do not install this library
417 if bld.env['HAVE_VTE'] == 1:
418 geany_sources.add('src/vte.c')
420 geany_sources.add('src/win32.c')
421 geany_sources.add('geany_private.rc')
424 features = ['c', 'cxx', 'cprogram'],
427 source = geany_sources,
428 includes = ['.', 'scintilla/include', 'tagmanager/src'],
429 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
430 uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET', 'M'],
431 use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
435 source = ['plugins/genapi.py', 'src/plugins.c'],
436 name = 'geanyfunctions.h',
437 before = ['c', 'cxx'],
438 cwd = '%s/plugins' % bld.path.abspath(),
439 rule = '%s genapi.py -q' % sys.executable)
442 if bld.env['HAVE_PLUGINS'] == 1:
443 build_plugin('classbuilder')
444 build_plugin('demoplugin', False)
445 build_plugin('export', uselib_add=['M'])
446 build_plugin('filebrowser')
447 build_plugin('htmlchars')
448 build_plugin('saveactions')
449 build_plugin('splitwindow')
452 if bld.env['INTLTOOL']:
454 features = ['linguas', 'intltool_po'],
456 install_path = '${LOCALEDIR}',
461 # replace backward slashes by forward slashes as they could be interepreted as escape
463 geany_pc_prefix = bld.env['PREFIX'].replace('\\', '/')
465 geany_pc_prefix = bld.env['PREFIX']
467 source = 'geany.pc.in',
468 dct = {'VERSION': VERSION,
469 'DEPENDENCIES': '%s >= %s glib-2.0 >= %s' % \
470 (bld.env['gtk_package_name'],
471 bld.env['minimum_gtk_version'],
472 MINIMUM_GLIB_VERSION),
473 'prefix': geany_pc_prefix,
474 'exec_prefix': '${prefix}',
475 'libdir': '${exec_prefix}/lib',
476 'includedir': '${prefix}/include',
477 'datarootdir': '${prefix}/share',
478 'datadir': '${datarootdir}',
479 'localedir': '${datarootdir}/locale'})
483 if bld.env['INTLTOOL']:
485 features = 'intltool_in',
486 source = 'geany.desktop.in',
487 flags = ['-d', '-q', '-u', '-c'],
488 install_path = '${DATADIR}/applications')
493 source = 'doc/geany.1.in',
495 dct = {'VERSION': VERSION,
496 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
497 install_path = '${MANDIR}/man1')
502 source = 'geany.spec.in',
503 target = 'geany.spec',
505 dct = {'VERSION': VERSION})
510 source = 'doc/Doxyfile.in',
511 target = 'doc/Doxyfile',
513 dct = {'VERSION': VERSION,
514 'top_builddir': bld.out_dir,
515 'top_srcdir': bld.top_dir,})
521 bld.install_files('${PREFIX}/include/geany', '''
522 src/app.h src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
523 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
524 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
525 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h src/gtkcompat.h
526 plugins/geanyplugin.h plugins/geanyfunctions.h''')
527 bld.install_files('${PREFIX}/include/geany/scintilla', '''
528 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
529 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
530 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
531 tagmanager/src/tm_file_entry.h tagmanager/src/tm_project.h
532 tagmanager/src/tm_source_file.h tagmanager/src/tm_parser.h
533 tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
534 tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.h
535 tagmanager/src/tm_workspace.h ''')
537 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
538 ext = '.txt' if is_win32 else ''
539 html_dir = '' if is_win32 else 'html/'
540 html_name = 'Manual.html' if is_win32 else 'index.html'
541 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
542 basename = _uc_first(filename, bld)
543 destination_filename = '%s%s' % (basename, ext)
544 destination = os.path.join(base_dir, destination_filename)
545 bld.install_as(destination, filename)
547 start_dir = bld.path.find_dir('doc/images')
548 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
549 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
550 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
551 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
553 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
554 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
556 data_dir = '' if is_win32 else 'geany'
557 start_dir = bld.path.find_dir('data')
558 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
559 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
560 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
561 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
562 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
563 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
564 if bld.env['use_gtk3']:
565 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.css')
567 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
569 start_dir = bld.path.find_dir('data/colorschemes')
570 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
571 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
572 start_dir = bld.path.find_dir('data/templates')
573 template_dest = '${DATADIR}/%s/templates' % data_dir
574 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
576 for dest, srcs in geany_icons.items():
577 dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
578 bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
579 # install theme indexes on Windows
581 for dest, srcs in geany_icons_indexes.items():
582 bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
586 Scripting.distclean(ctx)
587 _remove_linguas_file()
590 def _remove_linguas_file():
591 # remove LINGUAS file as well
593 os.unlink(LINGUAS_FILE)
599 @before_method('apply_intltool_po')
600 def write_linguas_file(self):
601 if os.path.exists(LINGUAS_FILE):
604 if 'LINGUAS' in self.env:
605 files = self.env['LINGUAS']
606 for po_filename in files.split(' '):
607 if os.path.exists('po/%s.po' % po_filename):
608 linguas += '%s ' % po_filename
610 files = os.listdir('%s/po' % self.path.abspath())
612 for filename in files:
613 if filename.endswith('.po'):
614 linguas += '%s ' % filename[:-3]
615 file_h = open(LINGUAS_FILE, 'w')
616 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
620 def _post_install(ctx):
621 is_win32 = _target_is_win32(ctx)
624 for d in 'hicolor', 'Tango':
625 theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
626 icon_cache_updated = False
627 if not ctx.options.destdir:
628 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
629 Logs.pprint('GREEN', 'GTK icon cache updated.')
630 icon_cache_updated = True
631 if not icon_cache_updated:
632 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
633 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
637 """update the message catalogs for internationalization"""
638 potfile = '%s.pot' % APPNAME
639 os.chdir('%s/po' % top)
642 old_size = os.stat(potfile).st_size
645 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
646 size_new = os.stat(potfile).st_size
647 if size_new != old_size:
648 Logs.pprint('CYAN', 'Updated POT file.')
649 Logs.pprint('CYAN', 'Updating translations')
650 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
652 Logs.pprint('RED', 'Updating translations failed')
654 Logs.pprint('CYAN', 'POT file is up to date.')
656 Logs.pprint('RED', 'Failed to generate pot file.')
660 """generate API reference documentation"""
661 basedir = ctx.path.abspath()
662 doxygen = _find_program(ctx, 'doxygen')
663 doxyfile = '%s/%s/doc/Doxyfile' % (basedir, out)
665 Logs.pprint('CYAN', 'Generating API documentation')
666 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
668 raise WafError('Generating API documentation failed')
669 # update hacking.html
670 cmd = _find_rst2html(ctx)
671 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, '../HACKING', 'hacking.html'))
676 """generate HTML documentation"""
677 # first try rst2html.py as it is the upstream default, fall back to rst2html
678 cmd = _find_rst2html(ctx)
680 Logs.pprint('CYAN', 'Generating HTML documentation')
681 ctx.exec_command('%s -stg --stylesheet=geany.css %s %s' % (cmd, 'geany.txt', 'geany.html'))
685 def _find_program(ctx, cmd, **kw):
689 ctx = ConfigurationContext()
692 return ctx.find_program(cmd, **kw)
695 def _find_rst2html(ctx):
696 cmds = ['rst2html.py', 'rst2html']
698 cmd = _find_program(ctx, command, mandatory=False)
703 'rst2html.py could not be found. Please install the Python docutils package.')
707 def _add_define_to_env(conf, key):
708 value = conf.get_define(key)
710 value = value.replace('"', '')
711 conf.env[key] = value
714 def _add_to_env_and_define(conf, key, value, quote=False):
715 conf.define(key, value, quote)
716 conf.env[key] = value
719 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
720 value = default_value
722 if isinstance(opt_value, bool):
726 if value is not None:
727 _add_to_env_and_define(conf, define_name, value, quote)
729 conf.undefine(define_name)
732 def _get_git_rev(conf):
733 if conf.options.no_scm:
736 if not os.path.isdir('.git'):
740 cmd = 'git rev-parse --short --revs-only HEAD'
741 revision = conf.cmd_and_log(cmd).strip()
748 def _load_intltool_if_available(conf):
750 conf.load('intltool')
751 if 'LINGUAS' in os.environ:
752 conf.env['LINGUAS'] = os.environ['LINGUAS']
754 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
755 if not _target_is_win32(conf):
759 def _target_is_win32(ctx):
760 if 'is_win32' in ctx.env:
762 return ctx.env['is_win32']
764 if sys.platform == 'win32':
767 if ctx.env and 'CC' in ctx.env:
768 env_cc = ctx.env['CC']
769 if not isinstance(env_cc, str):
770 env_cc = ''.join(env_cc)
771 is_win32 = (env_cc.find('mingw') != -1)
774 # cache for future checks
775 ctx.env['is_win32'] = is_win32
779 def _uc_first(string, ctx):
780 if _target_is_win32(ctx):
781 return string.title()