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.Build import BuildContext
47 from waflib.Configure import ConfigurationContext
48 from waflib.Errors import WafError
49 from waflib.TaskGen import feature, before_method
50 from waflib.Tools.compiler_c import c_compiler
51 from waflib.Tools.compiler_cxx import cxx_compiler
56 LINGUAS_FILE = os.path.join('po', 'LINGUAS')
57 MINIMUM_GTK_VERSION = '2.16.0'
58 MINIMUM_GTK3_VERSION = '3.0.0'
59 MINIMUM_GLIB_VERSION = '2.20.0'
65 mio_sources = set(['tagmanager/mio/mio.c'])
68 'tagmanager/ctags/abaqus.c',
69 'tagmanager/ctags/args.c',
70 'tagmanager/ctags/abc.c',
71 'tagmanager/ctags/actionscript.c',
72 'tagmanager/ctags/asciidoc.c',
73 'tagmanager/ctags/asm.c',
74 'tagmanager/ctags/basic.c',
75 'tagmanager/ctags/c.c',
76 'tagmanager/ctags/cobol.c',
77 'tagmanager/ctags/conf.c',
78 'tagmanager/ctags/css.c',
79 'tagmanager/ctags/ctags.c',
80 'tagmanager/ctags/diff.c',
81 'tagmanager/ctags/docbook.c',
82 'tagmanager/ctags/entry.c',
83 'tagmanager/ctags/fortran.c',
84 'tagmanager/ctags/get.c',
85 'tagmanager/ctags/haskell.c',
86 'tagmanager/ctags/haxe.c',
87 'tagmanager/ctags/html.c',
88 'tagmanager/ctags/js.c',
89 'tagmanager/ctags/keyword.c',
90 'tagmanager/ctags/latex.c',
91 'tagmanager/ctags/lregex.c',
92 'tagmanager/ctags/lua.c',
93 'tagmanager/ctags/make.c',
94 'tagmanager/ctags/markdown.c',
95 'tagmanager/ctags/matlab.c',
96 'tagmanager/ctags/nsis.c',
97 'tagmanager/ctags/nestlevel.c',
98 'tagmanager/ctags/objc.c',
99 'tagmanager/ctags/options.c',
100 'tagmanager/ctags/parse.c',
101 'tagmanager/ctags/pascal.c',
102 'tagmanager/ctags/r.c',
103 'tagmanager/ctags/perl.c',
104 'tagmanager/ctags/php.c',
105 'tagmanager/ctags/python.c',
106 'tagmanager/ctags/read.c',
107 'tagmanager/ctags/rest.c',
108 'tagmanager/ctags/ruby.c',
109 'tagmanager/ctags/rust.c',
110 'tagmanager/ctags/sh.c',
111 'tagmanager/ctags/sort.c',
112 'tagmanager/ctags/sql.c',
113 'tagmanager/ctags/strlist.c',
114 'tagmanager/ctags/txt2tags.c',
115 'tagmanager/ctags/tcl.c',
116 'tagmanager/ctags/vhdl.c',
117 'tagmanager/ctags/verilog.c',
118 'tagmanager/ctags/vstring.c'])
120 tagmanager_sources = set([
121 'tagmanager/src/tm_source_file.c',
122 'tagmanager/src/tm_tag.c',
123 'tagmanager/src/tm_workspace.c'])
125 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
127 geany_sources = set([
128 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
129 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
130 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
131 'src/highlighting.c', 'src/keybindings.c',
132 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
133 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
134 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
136 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
137 'src/ui_utils.c', 'src/utils.c'])
140 'hicolor/16x16/apps': ['16x16/classviewer-class.png',
141 '16x16/classviewer-macro.png',
142 '16x16/classviewer-member.png',
143 '16x16/classviewer-method.png',
144 '16x16/classviewer-namespace.png',
145 '16x16/classviewer-other.png',
146 '16x16/classviewer-struct.png',
147 '16x16/classviewer-var.png',
149 'hicolor/16x16/actions': ['16x16/geany-build.png',
150 '16x16/geany-close-all.png',
151 '16x16/geany-save-all.png'],
152 'hicolor/24x24/actions': ['24x24/geany-build.png',
153 '24x24/geany-close-all.png',
154 '24x24/geany-save-all.png'],
155 'hicolor/32x32/actions': ['32x32/geany-build.png',
156 '32x32/geany-close-all.png',
157 '32x32/geany-save-all.png'],
158 'hicolor/48x48/actions': ['48x48/geany-build.png',
159 '48x48/geany-close-all.png',
160 '48x48/geany-save-all.png'],
161 'hicolor/48x48/apps': ['48x48/geany.png'],
162 'hicolor/scalable/apps': ['scalable/geany.svg'],
163 'hicolor/scalable/actions': ['scalable/geany-build.svg',
164 'scalable/geany-close-all.svg',
165 'scalable/geany-save-all.svg'],
166 'Tango/16x16/actions': ['tango/16x16/geany-save-all.png'],
167 'Tango/24x24/actions': ['tango/24x24/geany-save-all.png'],
168 'Tango/32x32/actions': ['tango/32x32/geany-save-all.png'],
169 'Tango/48x48/actions': ['tango/48x48/geany-save-all.png'],
170 'Tango/scalable/actions': ['tango/scalable/geany-save-all.svg']
172 geany_icons_indexes = {
173 'hicolor': ['index.theme'],
174 'Tango': ['tango/index.theme']
180 conf.check_waf_version(mini='1.6.1')
182 conf.load('compiler_c')
183 is_win32 = _target_is_win32(conf)
185 conf.check_cc(header_name='fcntl.h', mandatory=False)
186 conf.check_cc(header_name='fnmatch.h', mandatory=False)
187 conf.check_cc(header_name='glob.h', mandatory=False)
188 conf.check_cc(header_name='sys/time.h', mandatory=False)
189 conf.check_cc(header_name='sys/types.h', mandatory=False)
190 conf.check_cc(header_name='sys/stat.h', mandatory=False)
191 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
192 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
193 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
195 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
196 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
197 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
198 conf.check_cc(function_name='strstr', header_name='string.h')
200 conf.check_cc(function_name='pow', header_name='math.h', lib='m', uselib_store='M')
202 # check sunOS socket support
203 if Options.platform == 'sunos':
204 conf.check_cc(function_name='socket', lib='socket',
205 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
207 # check for cxx after the header and function checks have been done to ensure they are
208 # checked with cc not cxx
209 conf.load('compiler_cxx')
212 _load_intltool_if_available(conf)
214 # GTK / GIO version check
215 gtk_package_name = 'gtk+-3.0' if conf.options.use_gtk3 else 'gtk+-2.0'
216 minimum_gtk_version = MINIMUM_GTK3_VERSION if conf.options.use_gtk3 else MINIMUM_GTK_VERSION
217 conf.check_cfg(package=gtk_package_name, atleast_version=minimum_gtk_version, uselib_store='GTK',
218 mandatory=True, args='--cflags --libs')
219 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
220 mandatory=True, args='--cflags --libs')
221 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
222 mandatory=True, args='--cflags --libs')
223 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
224 gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
225 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
226 # remember GTK version for the build step
227 conf.env['gtk_package_name'] = gtk_package_name
228 conf.env['minimum_gtk_version'] = minimum_gtk_version
229 conf.env['use_gtk3'] = conf.options.use_gtk3
231 revision = _get_git_rev(conf)
233 # rst2html for the HTML manual
234 if not conf.options.no_html_doc and revision is not None:
236 conf.env['RST2HTML'] = _find_rst2html(conf)
238 error_msg = '''Documentation enabled but rst2html not found.
239 You can explicitly disable building of the HTML manual with --disable-html-docs,
240 but you then may not have a local copy of the HTML manual.'''
241 raise WafError(error_msg)
245 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
246 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
247 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
248 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
249 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
250 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
251 _add_to_env_and_define(conf, 'LIBDIR', '%s/lib' % conf.env['PREFIX'], quote=True)
252 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
253 # overwrite LOCALEDIR to install message catalogues properly
254 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share', 'locale')
255 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
256 conf.undefine('DATADIR')
257 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
258 conf.env.append_value('LINKFLAGS_cprogram', [
261 '-static-libstdc++'])
262 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
263 # explicitly define Windows version for older Mingw environments
264 conf.define('WINVER', '0x0501', quote=False) # for SHGetFolderPathAndSubDirW
265 conf.define('_WIN32_IE', '0x0500', quote=False) # for SHGFP_TYPE
267 conf.env['cshlib_PATTERN'] = '%s.so'
268 # DATADIR and LOCALEDIR are defined by the intltool tool
269 # but they are not added to the environment, so we need to
270 _add_define_to_env(conf, 'DATADIR')
271 _add_define_to_env(conf, 'LOCALEDIR')
272 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
273 libdir = os.path.join(conf.env['PREFIX'], 'lib')
274 mandir = os.path.join(conf.env['DATADIR'], 'man')
275 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
276 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
277 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
279 conf.define('ENABLE_NLS', 1)
280 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
281 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
282 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
283 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
284 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
285 conf.define('PACKAGE', APPNAME, quote=True)
286 conf.define('VERSION', VERSION, quote=True)
287 conf.define('REVISION', revision or '-1', quote=True)
289 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
293 conf.options.no_vte = True
295 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
296 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
297 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
299 conf.write_config_header('config.h', remove=False)
301 # some more compiler flags
302 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
303 if conf.env['CC_NAME'] == 'gcc' and '-O' not in ''.join(conf.env['CFLAGS']):
304 conf.env.append_value('CFLAGS', ['-O2'])
305 if revision is not None:
306 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
308 conf.env.append_value('CFLAGS', ['-DGTK'])
309 conf.env.append_value('CXXFLAGS',
310 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
313 Logs.pprint('BLUE', 'Summary:')
314 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
315 conf.msg('Using GTK version', gtk_version)
316 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
317 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
318 if revision is not None:
319 conf.msg('Compiling Git revision', revision)
323 # Disable MSVC detection on win32: building Geany with MSVC is currently not supported
324 # If anyone wants to add support for building with MSVC, this hack should be removed.
325 c_compiler['win32'] = ['gcc']
326 cxx_compiler['win32'] = ['g++']
328 opt.load('compiler_cc')
329 opt.load('compiler_cxx')
333 opt.add_option('--no-scm', action='store_true', default=False,
334 help='Disable SCM detection [default: No]', dest='no_scm')
336 opt.add_option('--disable-plugins', action='store_true', default=False,
337 help='compile without plugin support [default: No]', dest='no_plugins')
338 opt.add_option('--disable-socket', action='store_true', default=False,
339 help='compile without support to detect a running instance [[default: No]',
341 opt.add_option('--disable-vte', action='store_true', default=False,
342 help='compile without support for an embedded virtual terminal [[default: No]',
344 opt.add_option('--enable-gtk3', action='store_true', default=False,
345 help='compile with GTK3 support (experimental) [[default: No]',
347 opt.add_option('--disable-html-docs', action='store_true', default=False,
348 help='do not generate HTML documentation using rst2html [[default: No]',
351 opt.add_option('--mandir', type='string', default='',
352 help='man documentation', dest='mandir')
353 opt.add_option('--docdir', type='string', default='',
354 help='documentation root', dest='docdir')
355 opt.add_option('--libdir', type='string', default='',
356 help='object code libraries', dest='libdir')
360 is_win32 = _target_is_win32(bld)
362 if bld.cmd == 'clean':
363 _remove_linguas_file()
364 if bld.cmd in ('install', 'uninstall'):
365 bld.add_post_fun(_post_install)
367 def build_plugin(plugin_name, install=True, uselib_add=[]):
369 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
374 features = ['c', 'cshlib'],
375 source = 'plugins/%s.c' % plugin_name,
376 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
377 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
378 target = plugin_name,
379 uselib = ['GTK', 'GLIB', 'GMODULE'] + uselib_add,
380 install_path = instpath)
384 features = ['c', 'cstlib'],
385 source = ctags_sources,
388 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
389 defines = 'G_LOG_DOMAIN="CTags"',
391 install_path = None) # do not install this library
395 features = ['c', 'cstlib'],
396 source = tagmanager_sources,
398 target = 'tagmanager',
399 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
400 defines = ['GEANY_PRIVATE', 'G_LOG_DOMAIN="Tagmanager"'],
401 uselib = ['GTK', 'GLIB'],
402 install_path = None) # do not install this library
406 features = ['c', 'cstlib'],
407 source = mio_sources,
410 includes = ['.', 'tagmanager/mio/'],
411 defines = 'G_LOG_DOMAIN="MIO"',
412 uselib = ['GTK', 'GLIB'],
413 install_path = None) # do not install this library
416 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
417 scintilla_sources.update(files)
419 features = ['c', 'cxx', 'cxxstlib'],
421 target = 'scintilla',
422 source = scintilla_sources,
423 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
424 uselib = ['GTK', 'GLIB', 'GMODULE', 'M'],
425 install_path = None) # do not install this library
428 if bld.env['HAVE_VTE'] == 1:
429 geany_sources.add('src/vte.c')
431 geany_sources.add('src/win32.c')
432 geany_sources.add('geany_private.rc')
435 features = ['c', 'cxx', 'cprogram'],
438 source = geany_sources,
439 includes = ['.', 'scintilla/include', 'tagmanager/src'],
440 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
441 uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET', 'M'],
442 use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
446 source = ['plugins/genapi.py', 'src/plugins.c'],
447 name = 'geanyfunctions.h',
448 before = ['c', 'cxx'],
449 cwd = '%s/plugins' % bld.path.abspath(),
450 rule = '%s genapi.py -q' % sys.executable)
453 if bld.env['HAVE_PLUGINS'] == 1:
454 build_plugin('classbuilder')
455 build_plugin('demoplugin', False)
456 build_plugin('export', uselib_add=['M'])
457 build_plugin('filebrowser')
458 build_plugin('htmlchars')
459 build_plugin('saveactions')
460 build_plugin('splitwindow')
463 if bld.env['INTLTOOL']:
465 features = ['linguas', 'intltool_po'],
467 install_path = '${LOCALEDIR}',
470 # HTML documentation (build if it is not part of the tree already, as it is required for install)
471 html_doc_filename = os.path.join(bld.out_dir, 'doc', 'geany.html')
472 if bld.env['RST2HTML']:
473 rst2html = bld.env['RST2HTML']
475 source = ['doc/geany.txt'],
476 deps = ['doc/geany.css'],
477 target = 'doc/geany.html',
479 cwd = os.path.join(bld.path.abspath(), 'doc'),
480 rule = '%s -stg --stylesheet=geany.css geany.txt %s' % (rst2html, html_doc_filename))
484 # replace backward slashes by forward slashes as they could be interepreted as escape
486 geany_pc_prefix = bld.env['PREFIX'].replace('\\', '/')
488 geany_pc_prefix = bld.env['PREFIX']
490 source = 'geany.pc.in',
491 dct = {'VERSION': VERSION,
492 'DEPENDENCIES': '%s >= %s glib-2.0 >= %s' % \
493 (bld.env['gtk_package_name'],
494 bld.env['minimum_gtk_version'],
495 MINIMUM_GLIB_VERSION),
496 'prefix': geany_pc_prefix,
497 'exec_prefix': '${prefix}',
498 'libdir': '${exec_prefix}/lib',
499 'includedir': '${prefix}/include',
500 'datarootdir': '${prefix}/share',
501 'datadir': '${datarootdir}',
502 'localedir': '${datarootdir}/locale'})
506 if bld.env['INTLTOOL']:
508 features = 'intltool_in',
509 source = 'geany.desktop.in',
510 flags = ['-d', '-q', '-u', '-c'],
511 install_path = '${DATADIR}/applications')
516 source = 'doc/geany.1.in',
518 dct = {'VERSION': VERSION,
519 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
520 install_path = '${MANDIR}/man1')
525 source = 'geany.spec.in',
526 target = 'geany.spec',
528 dct = {'VERSION': VERSION})
533 source = 'doc/Doxyfile.in',
534 target = 'doc/Doxyfile',
536 dct = {'VERSION': VERSION,
537 'top_builddir': bld.out_dir,
538 'top_srcdir': bld.top_dir,})
544 bld.install_files('${PREFIX}/include/geany', '''
545 src/app.h src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
546 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
547 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
548 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h src/gtkcompat.h
549 plugins/geanyplugin.h plugins/geanyfunctions.h''')
550 bld.install_files('${PREFIX}/include/geany/scintilla', '''
551 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
552 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
553 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
554 tagmanager/src/tm_source_file.h
555 tagmanager/src/tm_tag.h
556 tagmanager/src/tm_tagmanager.h
557 tagmanager/src/tm_workspace.h ''')
559 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
560 ext = '.txt' if is_win32 else ''
561 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
562 basename = _uc_first(filename, bld)
563 destination_filename = '%s%s' % (basename, ext)
564 destination = os.path.join(base_dir, destination_filename)
565 bld.install_as(destination, filename)
567 # install HTML documentation only if it exists, i.e. it was built before
568 # local_html_doc_filename supports installing HTML doc from in-tree geany.html if it exists
569 local_html_doc_filename = os.path.join(bld.path.abspath(), 'doc', 'geany.html')
570 if os.path.exists(html_doc_filename) or os.path.exists(local_html_doc_filename):
571 html_dir = '' if is_win32 else 'html/'
572 html_name = 'Manual.html' if is_win32 else 'index.html'
573 start_dir = bld.path.find_dir('doc/images')
574 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
575 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
577 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
578 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
580 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
581 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
583 data_dir = '' if is_win32 else 'geany'
584 start_dir = bld.path.find_dir('data')
585 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
586 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
587 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
588 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
589 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
590 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
591 if bld.env['use_gtk3']:
592 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.css')
594 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
596 start_dir = bld.path.find_dir('data/colorschemes')
597 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
598 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
599 start_dir = bld.path.find_dir('data/templates')
600 template_dest = '${DATADIR}/%s/templates' % data_dir
601 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
603 for dest, srcs in geany_icons.items():
604 dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
605 bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
606 # install theme indexes on Windows
608 for dest, srcs in geany_icons_indexes.items():
609 bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
613 Scripting.distclean(ctx)
614 _remove_linguas_file()
617 def _remove_linguas_file():
618 # remove LINGUAS file as well
620 os.unlink(LINGUAS_FILE)
626 @before_method('apply_intltool_po')
627 def write_linguas_file(self):
628 if os.path.exists(LINGUAS_FILE):
631 if 'LINGUAS' in self.env:
632 files = self.env['LINGUAS']
633 for po_filename in files.split(' '):
634 if os.path.exists('po/%s.po' % po_filename):
635 linguas += '%s ' % po_filename
637 files = os.listdir('%s/po' % self.path.abspath())
639 for filename in files:
640 if filename.endswith('.po'):
641 linguas += '%s ' % filename[:-3]
642 file_h = open(LINGUAS_FILE, 'w')
643 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
647 def _post_install(ctx):
648 is_win32 = _target_is_win32(ctx)
651 for d in 'hicolor', 'Tango':
652 theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
653 icon_cache_updated = False
654 if not ctx.options.destdir:
655 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
656 Logs.pprint('GREEN', 'GTK icon cache updated.')
657 icon_cache_updated = True
658 if not icon_cache_updated:
659 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
660 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
664 """update the message catalogs for internationalization"""
665 potfile = '%s.pot' % APPNAME
666 os.chdir('%s/po' % top)
669 old_size = os.stat(potfile).st_size
672 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
673 size_new = os.stat(potfile).st_size
674 if size_new != old_size:
675 Logs.pprint('CYAN', 'Updated POT file.')
676 Logs.pprint('CYAN', 'Updating translations')
677 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
679 Logs.pprint('RED', 'Updating translations failed')
681 Logs.pprint('CYAN', 'POT file is up to date.')
683 Logs.pprint('RED', 'Failed to generate pot file.')
687 """generate API reference documentation"""
688 ctx = BuildContext() # create our own context to have ctx.top_dir
689 basedir = ctx.top_dir
690 doxygen = _find_program(ctx, 'doxygen')
691 doxyfile = '%s/doc/Doxyfile' % ctx.out_dir
692 Logs.pprint('CYAN', 'Generating API documentation')
693 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
695 raise WafError('Generating API documentation failed')
699 """generate HACKING documentation"""
700 ctx = BuildContext() # create our own context to have ctx.top_dir
701 Logs.pprint('CYAN', 'Generating HACKING documentation')
702 cmd = _find_rst2html(ctx)
703 hacking_file = os.path.join(ctx.top_dir, 'HACKING')
704 hacking_html_file = os.path.join(ctx.top_dir, 'doc', 'hacking.html')
705 stylesheet = os.path.join(ctx.top_dir, 'doc', 'geany.css')
706 ret = ctx.exec_command('%s -stg --stylesheet=%s %s %s' % (
707 cmd, stylesheet, hacking_file, hacking_html_file))
709 raise WafError('Generating HACKING documentation failed')
712 def _find_program(ctx, cmd, **kw):
716 if ctx is None or not isinstance(ctx, ConfigurationContext):
717 ctx = ConfigurationContext()
720 return ctx.find_program(cmd, **kw)
723 def _find_rst2html(ctx):
724 cmds = ['rst2html', 'rst2html2']
726 cmd = _find_program(ctx, command, mandatory=False, exts=',.py')
731 'rst2html.py could not be found. Please install the Python docutils package.')
735 def _add_define_to_env(conf, key):
736 value = conf.get_define(key)
738 value = value.replace('"', '')
739 conf.env[key] = value
742 def _add_to_env_and_define(conf, key, value, quote=False):
743 conf.define(key, value, quote)
744 conf.env[key] = value
747 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
748 value = default_value
750 if isinstance(opt_value, bool):
754 if value is not None:
755 _add_to_env_and_define(conf, define_name, value, quote)
757 conf.undefine(define_name)
760 def _get_git_rev(conf):
761 if conf.options.no_scm:
764 if not os.path.isdir('.git'):
768 cmd = 'git rev-parse --short --revs-only HEAD'
769 revision = conf.cmd_and_log(cmd).strip()
776 def _load_intltool_if_available(conf):
778 conf.load('intltool')
779 if 'LINGUAS' in os.environ:
780 conf.env['LINGUAS'] = os.environ['LINGUAS']
782 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
783 if not _target_is_win32(conf):
787 def _target_is_win32(ctx):
788 if 'is_win32' in ctx.env:
790 return ctx.env['is_win32']
792 if sys.platform == 'win32':
795 if ctx.env and 'CC' in ctx.env:
796 env_cc = ctx.env['CC']
797 if not isinstance(env_cc, str):
798 env_cc = ''.join(env_cc)
799 is_win32 = (env_cc.find('mingw') != -1)
802 # cache for future checks
803 ctx.env['is_win32'] = is_win32
807 def _uc_first(string, ctx):
808 if _target_is_win32(ctx):
809 return string.title()