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='fnmatch', header_name='fnmatch.h', mandatory=False)
197 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
198 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
199 conf.check_cc(function_name='strstr', header_name='string.h')
201 conf.check_cc(function_name='pow', header_name='math.h', lib='m', uselib_store='M')
203 # check sunOS socket support
204 if Options.platform == 'sunos':
205 conf.check_cc(function_name='socket', lib='socket',
206 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
208 # check for cxx after the header and function checks have been done to ensure they are
209 # checked with cc not cxx
210 conf.load('compiler_cxx')
213 _load_intltool_if_available(conf)
215 # GTK / GIO version check
216 gtk_package_name = 'gtk+-3.0' if conf.options.use_gtk3 else 'gtk+-2.0'
217 minimum_gtk_version = MINIMUM_GTK3_VERSION if conf.options.use_gtk3 else MINIMUM_GTK_VERSION
218 conf.check_cfg(package=gtk_package_name, atleast_version=minimum_gtk_version, uselib_store='GTK',
219 mandatory=True, args='--cflags --libs')
220 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
221 mandatory=True, args='--cflags --libs')
222 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
223 mandatory=True, args='--cflags --libs')
224 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
225 gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
226 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
227 # remember GTK version for the build step
228 conf.env['gtk_package_name'] = gtk_package_name
229 conf.env['minimum_gtk_version'] = minimum_gtk_version
230 conf.env['use_gtk3'] = conf.options.use_gtk3
232 revision = _get_git_rev(conf)
234 # rst2html for the HTML manual
235 if not conf.options.no_html_doc and revision is not None:
237 conf.env['RST2HTML'] = _find_rst2html(conf)
239 error_msg = '''Documentation enabled but rst2html not found.
240 You can explicitly disable building of the HTML manual with --disable-html-docs,
241 but you then may not have a local copy of the HTML manual.'''
242 raise WafError(error_msg)
246 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
247 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
248 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
249 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
250 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
251 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
252 _add_to_env_and_define(conf, 'LIBDIR', '%s/lib' % conf.env['PREFIX'], quote=True)
253 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
254 # overwrite LOCALEDIR to install message catalogues properly
255 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share', 'locale')
256 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
257 conf.undefine('DATADIR')
258 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
259 conf.env.append_value('LINKFLAGS_cprogram', [
262 '-static-libstdc++'])
263 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32'])
264 # explicitly define Windows version for older Mingw environments
265 conf.define('WINVER', '0x0501', quote=False) # for SHGetFolderPathAndSubDirW
266 conf.define('_WIN32_IE', '0x0500', quote=False) # for SHGFP_TYPE
268 conf.env['cshlib_PATTERN'] = '%s.so'
269 # DATADIR and LOCALEDIR are defined by the intltool tool
270 # but they are not added to the environment, so we need to
271 _add_define_to_env(conf, 'DATADIR')
272 _add_define_to_env(conf, 'LOCALEDIR')
273 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
274 libdir = os.path.join(conf.env['PREFIX'], 'lib')
275 mandir = os.path.join(conf.env['DATADIR'], 'man')
276 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
277 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
278 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
280 conf.define('ENABLE_NLS', 1)
281 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
282 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
283 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
284 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
285 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
286 conf.define('PACKAGE', APPNAME, quote=True)
287 conf.define('VERSION', VERSION, quote=True)
288 conf.define('REVISION', revision or '-1', quote=True)
290 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
294 conf.options.no_vte = True
296 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
297 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
298 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
300 conf.write_config_header('config.h', remove=False)
302 # some more compiler flags
303 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
304 if conf.env['CC_NAME'] == 'gcc' and '-O' not in ''.join(conf.env['CFLAGS']):
305 conf.env.append_value('CFLAGS', ['-O2'])
306 if revision is not None:
307 conf.env.append_value('CFLAGS', ['-g', '-DGEANY_DEBUG'])
309 conf.env.append_value('CFLAGS', ['-DGTK'])
310 conf.env.append_value('CXXFLAGS',
311 ['-DNDEBUG', '-DGTK', '-DSCI_LEXER', '-DG_THREADS_IMPL_NONE'])
314 Logs.pprint('BLUE', 'Summary:')
315 conf.msg('Install Geany ' + VERSION + ' in', conf.env['PREFIX'])
316 conf.msg('Using GTK version', gtk_version)
317 conf.msg('Build with plugin support', conf.options.no_plugins and 'no' or 'yes')
318 conf.msg('Use virtual terminal support', conf.options.no_vte and 'no' or 'yes')
319 if revision is not None:
320 conf.msg('Compiling Git revision', revision)
324 # Disable MSVC detection on win32: building Geany with MSVC is currently not supported
325 # If anyone wants to add support for building with MSVC, this hack should be removed.
326 c_compiler['win32'] = ['gcc']
327 cxx_compiler['win32'] = ['g++']
329 opt.load('compiler_cc')
330 opt.load('compiler_cxx')
334 opt.add_option('--no-scm', action='store_true', default=False,
335 help='Disable SCM detection [default: No]', dest='no_scm')
337 opt.add_option('--disable-plugins', action='store_true', default=False,
338 help='compile without plugin support [default: No]', dest='no_plugins')
339 opt.add_option('--disable-socket', action='store_true', default=False,
340 help='compile without support to detect a running instance [[default: No]',
342 opt.add_option('--disable-vte', action='store_true', default=False,
343 help='compile without support for an embedded virtual terminal [[default: No]',
345 opt.add_option('--enable-gtk3', action='store_true', default=False,
346 help='compile with GTK3 support (experimental) [[default: No]',
348 opt.add_option('--disable-html-docs', action='store_true', default=False,
349 help='do not generate HTML documentation using rst2html [[default: No]',
352 opt.add_option('--mandir', type='string', default='',
353 help='man documentation', dest='mandir')
354 opt.add_option('--docdir', type='string', default='',
355 help='documentation root', dest='docdir')
356 opt.add_option('--libdir', type='string', default='',
357 help='object code libraries', dest='libdir')
361 is_win32 = _target_is_win32(bld)
363 if bld.cmd == 'clean':
364 _remove_linguas_file()
365 if bld.cmd in ('install', 'uninstall'):
366 bld.add_post_fun(_post_install)
368 def build_plugin(plugin_name, install=True, uselib_add=[]):
370 instpath = '${PREFIX}/lib' if is_win32 else '${LIBDIR}/geany'
375 features = ['c', 'cshlib'],
376 source = 'plugins/%s.c' % plugin_name,
377 includes = ['.', 'src/', 'scintilla/include', 'tagmanager/src'],
378 defines = 'G_LOG_DOMAIN="%s"' % plugin_name,
379 target = plugin_name,
380 uselib = ['GTK', 'GLIB', 'GMODULE'] + uselib_add,
381 install_path = instpath)
385 features = ['c', 'cstlib'],
386 source = ctags_sources,
389 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
390 defines = 'G_LOG_DOMAIN="CTags"',
392 install_path = None) # do not install this library
396 features = ['c', 'cstlib'],
397 source = tagmanager_sources,
399 target = 'tagmanager',
400 includes = ['.', 'tagmanager', 'tagmanager/ctags'],
401 defines = ['GEANY_PRIVATE', 'G_LOG_DOMAIN="Tagmanager"'],
402 uselib = ['GTK', 'GLIB'],
403 install_path = None) # do not install this library
407 features = ['c', 'cstlib'],
408 source = mio_sources,
411 includes = ['.', 'tagmanager/mio/'],
412 defines = 'G_LOG_DOMAIN="MIO"',
413 uselib = ['GTK', 'GLIB'],
414 install_path = None) # do not install this library
417 files = bld.srcnode.ant_glob('scintilla/**/*.cxx', src=True, dir=False)
418 scintilla_sources.update(files)
420 features = ['c', 'cxx', 'cxxstlib'],
422 target = 'scintilla',
423 source = scintilla_sources,
424 includes = ['.', 'scintilla/include', 'scintilla/src', 'scintilla/lexlib'],
425 uselib = ['GTK', 'GLIB', 'GMODULE', 'M'],
426 install_path = None) # do not install this library
429 if bld.env['HAVE_VTE'] == 1:
430 geany_sources.add('src/vte.c')
432 geany_sources.add('src/win32.c')
433 geany_sources.add('geany_private.rc')
436 features = ['c', 'cxx', 'cprogram'],
439 source = geany_sources,
440 includes = ['.', 'scintilla/include', 'tagmanager/src'],
441 defines = ['G_LOG_DOMAIN="Geany"', 'GEANY_PRIVATE'],
442 uselib = ['GTK', 'GLIB', 'GMODULE', 'GIO', 'GTHREAD', 'WIN32', 'SUNOS_SOCKET', 'M'],
443 use = ['scintilla', 'ctags', 'tagmanager', 'mio'])
447 source = ['plugins/genapi.py', 'src/plugins.c'],
448 name = 'geanyfunctions.h',
449 before = ['c', 'cxx'],
450 cwd = '%s/plugins' % bld.path.abspath(),
451 rule = '%s genapi.py -q' % sys.executable)
454 if bld.env['HAVE_PLUGINS'] == 1:
455 build_plugin('classbuilder')
456 build_plugin('demoplugin', False)
457 build_plugin('export', uselib_add=['M'])
458 build_plugin('filebrowser')
459 build_plugin('htmlchars')
460 build_plugin('saveactions')
461 build_plugin('splitwindow')
464 if bld.env['INTLTOOL']:
466 features = ['linguas', 'intltool_po'],
468 install_path = '${LOCALEDIR}',
471 # HTML documentation (build if it is not part of the tree already, as it is required for install)
472 html_doc_filename = os.path.join(bld.out_dir, 'doc', 'geany.html')
473 if bld.env['RST2HTML']:
474 rst2html = bld.env['RST2HTML']
476 source = ['doc/geany.txt'],
477 deps = ['doc/geany.css'],
478 target = 'doc/geany.html',
480 cwd = os.path.join(bld.path.abspath(), 'doc'),
481 rule = '%s -stg --stylesheet=geany.css geany.txt %s' % (rst2html, html_doc_filename))
485 # replace backward slashes by forward slashes as they could be interepreted as escape
487 geany_pc_prefix = bld.env['PREFIX'].replace('\\', '/')
489 geany_pc_prefix = bld.env['PREFIX']
491 source = 'geany.pc.in',
492 dct = {'VERSION': VERSION,
493 'DEPENDENCIES': '%s >= %s glib-2.0 >= %s' % \
494 (bld.env['gtk_package_name'],
495 bld.env['minimum_gtk_version'],
496 MINIMUM_GLIB_VERSION),
497 'prefix': geany_pc_prefix,
498 'exec_prefix': '${prefix}',
499 'libdir': '${exec_prefix}/lib',
500 'includedir': '${prefix}/include',
501 'datarootdir': '${prefix}/share',
502 'datadir': '${datarootdir}',
503 'localedir': '${datarootdir}/locale'})
507 if bld.env['INTLTOOL']:
509 features = 'intltool_in',
510 source = 'geany.desktop.in',
511 flags = ['-d', '-q', '-u', '-c'],
512 install_path = '${DATADIR}/applications')
517 source = 'doc/geany.1.in',
519 dct = {'VERSION': VERSION,
520 'GEANY_DATA_DIR': bld.env['DATADIR'] + '/geany'},
521 install_path = '${MANDIR}/man1')
526 source = 'geany.spec.in',
527 target = 'geany.spec',
529 dct = {'VERSION': VERSION})
534 source = 'doc/Doxyfile.in',
535 target = 'doc/Doxyfile',
537 dct = {'VERSION': VERSION,
538 'top_builddir': bld.out_dir,
539 'top_srcdir': bld.top_dir,})
545 bld.install_files('${PREFIX}/include/geany', '''
546 src/app.h src/document.h src/editor.h src/encodings.h src/filetypes.h src/geany.h
547 src/highlighting.h src/keybindings.h src/msgwindow.h src/plugindata.h
548 src/prefs.h src/project.h src/search.h src/stash.h src/support.h
549 src/templates.h src/toolbar.h src/ui_utils.h src/utils.h src/build.h src/gtkcompat.h
550 plugins/geanyplugin.h plugins/geanyfunctions.h''')
551 bld.install_files('${PREFIX}/include/geany/scintilla', '''
552 scintilla/include/SciLexer.h scintilla/include/Scintilla.h
553 scintilla/include/Scintilla.iface scintilla/include/ScintillaWidget.h ''')
554 bld.install_files('${PREFIX}/include/geany/tagmanager', '''
555 tagmanager/src/tm_source_file.h
556 tagmanager/src/tm_tag.h
557 tagmanager/src/tm_tagmanager.h
558 tagmanager/src/tm_workspace.h ''')
560 base_dir = '${PREFIX}' if is_win32 else '${DOCDIR}'
561 ext = '.txt' if is_win32 else ''
562 for filename in 'AUTHORS ChangeLog COPYING README NEWS THANKS TODO'.split():
563 basename = _uc_first(filename, bld)
564 destination_filename = '%s%s' % (basename, ext)
565 destination = os.path.join(base_dir, destination_filename)
566 bld.install_as(destination, filename)
568 # install HTML documentation only if it exists, i.e. it was built before
569 # local_html_doc_filename supports installing HTML doc from in-tree geany.html if it exists
570 local_html_doc_filename = os.path.join(bld.path.abspath(), 'doc', 'geany.html')
571 if os.path.exists(html_doc_filename) or os.path.exists(local_html_doc_filename):
572 html_dir = '' if is_win32 else 'html/'
573 html_name = 'Manual.html' if is_win32 else 'index.html'
574 start_dir = bld.path.find_dir('doc/images')
575 bld.install_files('${DOCDIR}/%simages' % html_dir, start_dir.ant_glob('*.png'), cwd=start_dir)
576 bld.install_as('${DOCDIR}/%s%s' % (html_dir, html_name), 'doc/geany.html')
578 bld.install_as('${DOCDIR}/%s' % _uc_first('manual.txt', bld), 'doc/geany.txt')
579 bld.install_as('${DOCDIR}/ScintillaLicense.txt', 'scintilla/License.txt')
581 bld.install_as('${DOCDIR}/ReadMe.I18n.txt', 'README.I18N')
582 bld.install_as('${DOCDIR}/Hacking.txt', 'HACKING')
584 data_dir = '' if is_win32 else 'geany'
585 start_dir = bld.path.find_dir('data')
586 bld.install_as('${DATADIR}/%s/GPL-2' % data_dir, 'COPYING')
587 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('filetype*'), cwd=start_dir)
588 bld.install_files('${DATADIR}/%s' % data_dir, start_dir.ant_glob('*.tags'), cwd=start_dir)
589 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.glade')
590 bld.install_files('${DATADIR}/%s' % data_dir, 'data/snippets.conf')
591 bld.install_files('${DATADIR}/%s' % data_dir, 'data/ui_toolbar.xml')
592 if bld.env['use_gtk3']:
593 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.css')
595 bld.install_files('${DATADIR}/%s' % data_dir, 'data/geany.gtkrc')
597 start_dir = bld.path.find_dir('data/colorschemes')
598 template_dest = '${DATADIR}/%s/colorschemes' % data_dir
599 bld.install_files(template_dest, start_dir.ant_glob('*'), cwd=start_dir)
600 start_dir = bld.path.find_dir('data/templates')
601 template_dest = '${DATADIR}/%s/templates' % data_dir
602 bld.install_files(template_dest, start_dir.ant_glob('**/*'), cwd=start_dir, relative_trick=True)
604 for dest, srcs in geany_icons.items():
605 dest_dir = os.path.join('${PREFIX}/share/icons' if is_win32 else '${DATADIR}/icons', dest)
606 bld.install_files(dest_dir, srcs, cwd=bld.path.find_dir('icons'))
607 # install theme indexes on Windows
609 for dest, srcs in geany_icons_indexes.items():
610 bld.install_files(os.path.join('${PREFIX}/share/icons', dest), srcs, cwd=bld.path.find_dir('icons'))
614 Scripting.distclean(ctx)
615 _remove_linguas_file()
618 def _remove_linguas_file():
619 # remove LINGUAS file as well
621 os.unlink(LINGUAS_FILE)
627 @before_method('apply_intltool_po')
628 def write_linguas_file(self):
629 if os.path.exists(LINGUAS_FILE):
632 if 'LINGUAS' in self.env:
633 files = self.env['LINGUAS']
634 for po_filename in files.split(' '):
635 if os.path.exists('po/%s.po' % po_filename):
636 linguas += '%s ' % po_filename
638 files = os.listdir('%s/po' % self.path.abspath())
640 for filename in files:
641 if filename.endswith('.po'):
642 linguas += '%s ' % filename[:-3]
643 file_h = open(LINGUAS_FILE, 'w')
644 file_h.write('# This file is autogenerated. Do not edit.\n%s\n' % linguas)
648 def _post_install(ctx):
649 is_win32 = _target_is_win32(ctx)
652 for d in 'hicolor', 'Tango':
653 theme_dir = Utils.subst_vars('${DATADIR}/icons/' + d, ctx.env)
654 icon_cache_updated = False
655 if not ctx.options.destdir:
656 ctx.exec_command('gtk-update-icon-cache -q -f -t %s' % theme_dir)
657 Logs.pprint('GREEN', 'GTK icon cache updated.')
658 icon_cache_updated = True
659 if not icon_cache_updated:
660 Logs.pprint('YELLOW', 'Icon cache not updated. After install, run this:')
661 Logs.pprint('YELLOW', 'gtk-update-icon-cache -q -f -t %s' % theme_dir)
665 """update the message catalogs for internationalization"""
666 potfile = '%s.pot' % APPNAME
667 os.chdir('%s/po' % top)
670 old_size = os.stat(potfile).st_size
673 ctx.exec_command('intltool-update --pot -g %s' % APPNAME)
674 size_new = os.stat(potfile).st_size
675 if size_new != old_size:
676 Logs.pprint('CYAN', 'Updated POT file.')
677 Logs.pprint('CYAN', 'Updating translations')
678 ret = ctx.exec_command('intltool-update -r -g %s' % APPNAME)
680 Logs.pprint('RED', 'Updating translations failed')
682 Logs.pprint('CYAN', 'POT file is up to date.')
684 Logs.pprint('RED', 'Failed to generate pot file.')
688 """generate API reference documentation"""
689 ctx = BuildContext() # create our own context to have ctx.top_dir
690 basedir = ctx.top_dir
691 doxygen = _find_program(ctx, 'doxygen')
692 doxyfile = '%s/doc/Doxyfile' % ctx.out_dir
693 Logs.pprint('CYAN', 'Generating API documentation')
694 ret = ctx.exec_command('%s %s' % (doxygen, doxyfile))
696 raise WafError('Generating API documentation failed')
700 """generate HACKING documentation"""
701 ctx = BuildContext() # create our own context to have ctx.top_dir
702 Logs.pprint('CYAN', 'Generating HACKING documentation')
703 cmd = _find_rst2html(ctx)
704 hacking_file = os.path.join(ctx.top_dir, 'HACKING')
705 hacking_html_file = os.path.join(ctx.top_dir, 'doc', 'hacking.html')
706 stylesheet = os.path.join(ctx.top_dir, 'doc', 'geany.css')
707 ret = ctx.exec_command('%s -stg --stylesheet=%s %s %s' % (
708 cmd, stylesheet, hacking_file, hacking_html_file))
710 raise WafError('Generating HACKING documentation failed')
713 def _find_program(ctx, cmd, **kw):
717 if ctx is None or not isinstance(ctx, ConfigurationContext):
718 ctx = ConfigurationContext()
721 return ctx.find_program(cmd, **kw)
724 def _find_rst2html(ctx):
725 cmds = ['rst2html', 'rst2html2']
727 cmd = _find_program(ctx, command, mandatory=False, exts=',.py')
732 'rst2html.py could not be found. Please install the Python docutils package.')
736 def _add_define_to_env(conf, key):
737 value = conf.get_define(key)
739 value = value.replace('"', '')
740 conf.env[key] = value
743 def _add_to_env_and_define(conf, key, value, quote=False):
744 conf.define(key, value, quote)
745 conf.env[key] = value
748 def _define_from_opt(conf, define_name, opt_value, default_value, quote=1):
749 value = default_value
751 if isinstance(opt_value, bool):
755 if value is not None:
756 _add_to_env_and_define(conf, define_name, value, quote)
758 conf.undefine(define_name)
761 def _get_git_rev(conf):
762 if conf.options.no_scm:
765 if not os.path.isdir('.git'):
769 cmd = 'git rev-parse --short --revs-only HEAD'
770 revision = conf.cmd_and_log(cmd).strip()
777 def _load_intltool_if_available(conf):
779 conf.load('intltool')
780 if 'LINGUAS' in os.environ:
781 conf.env['LINGUAS'] = os.environ['LINGUAS']
783 # on Windows, we don't hard depend on intltool, on all other platforms raise an error
784 if not _target_is_win32(conf):
788 def _target_is_win32(ctx):
789 if 'is_win32' in ctx.env:
791 return ctx.env['is_win32']
793 if sys.platform == 'win32':
796 if ctx.env and 'CC' in ctx.env:
797 env_cc = ctx.env['CC']
798 if not isinstance(env_cc, str):
799 env_cc = ''.join(env_cc)
800 is_win32 = (env_cc.find('mingw') != -1)
803 # cache for future checks
804 ctx.env['is_win32'] = is_win32
808 def _uc_first(string, ctx):
809 if _target_is_win32(ctx):
810 return string.title()