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_file_entry.c',
122 'tagmanager/src/tm_project.c',
123 'tagmanager/src/tm_source_file.c',
124 'tagmanager/src/tm_symbol.c',
125 'tagmanager/src/tm_tag.c',
126 'tagmanager/src/tm_tagmanager.c',
127 'tagmanager/src/tm_work_object.c',
128 'tagmanager/src/tm_workspace.c'])
130 scintilla_sources = set(['scintilla/gtk/scintilla-marshal.c'])
132 geany_sources = set([
133 'src/about.c', 'src/build.c', 'src/callbacks.c', 'src/dialogs.c', 'src/document.c',
134 'src/editor.c', 'src/encodings.c', 'src/filetypes.c', 'src/geanyentryaction.c',
135 'src/geanymenubuttonaction.c', 'src/geanyobject.c', 'src/geanywraplabel.c',
136 'src/highlighting.c', 'src/keybindings.c',
137 'src/keyfile.c', 'src/log.c', 'src/main.c', 'src/msgwindow.c', 'src/navqueue.c', 'src/notebook.c',
138 'src/plugins.c', 'src/pluginutils.c', 'src/prefix.c', 'src/prefs.c', 'src/printing.c', 'src/project.c',
139 'src/sciwrappers.c', 'src/search.c', 'src/socket.c', 'src/stash.c',
141 'src/templates.c', 'src/toolbar.c', 'src/tools.c', 'src/sidebar.c',
142 'src/ui_utils.c', 'src/utils.c'])
145 'hicolor/16x16/apps': ['16x16/classviewer-class.png',
146 '16x16/classviewer-macro.png',
147 '16x16/classviewer-member.png',
148 '16x16/classviewer-method.png',
149 '16x16/classviewer-namespace.png',
150 '16x16/classviewer-other.png',
151 '16x16/classviewer-struct.png',
152 '16x16/classviewer-var.png',
154 'hicolor/16x16/actions': ['16x16/geany-build.png',
155 '16x16/geany-close-all.png',
156 '16x16/geany-save-all.png'],
157 'hicolor/24x24/actions': ['24x24/geany-build.png',
158 '24x24/geany-close-all.png',
159 '24x24/geany-save-all.png'],
160 'hicolor/32x32/actions': ['32x32/geany-build.png',
161 '32x32/geany-close-all.png',
162 '32x32/geany-save-all.png'],
163 'hicolor/48x48/actions': ['48x48/geany-build.png',
164 '48x48/geany-close-all.png',
165 '48x48/geany-save-all.png'],
166 'hicolor/48x48/apps': ['48x48/geany.png'],
167 'hicolor/scalable/apps': ['scalable/geany.svg'],
168 'hicolor/scalable/actions': ['scalable/geany-build.svg',
169 'scalable/geany-close-all.svg',
170 'scalable/geany-save-all.svg'],
171 'Tango/16x16/actions': ['tango/16x16/geany-save-all.png'],
172 'Tango/24x24/actions': ['tango/24x24/geany-save-all.png'],
173 'Tango/32x32/actions': ['tango/32x32/geany-save-all.png'],
174 'Tango/48x48/actions': ['tango/48x48/geany-save-all.png'],
175 'Tango/scalable/actions': ['tango/scalable/geany-save-all.svg']
177 geany_icons_indexes = {
178 'hicolor': ['index.theme'],
179 'Tango': ['tango/index.theme']
185 conf.check_waf_version(mini='1.6.1')
187 conf.load('compiler_c')
188 is_win32 = _target_is_win32(conf)
190 conf.check_cc(header_name='fcntl.h', mandatory=False)
191 conf.check_cc(header_name='fnmatch.h', mandatory=False)
192 conf.check_cc(header_name='glob.h', mandatory=False)
193 conf.check_cc(header_name='sys/time.h', mandatory=False)
194 conf.check_cc(header_name='sys/types.h', mandatory=False)
195 conf.check_cc(header_name='sys/stat.h', mandatory=False)
196 conf.define('HAVE_STDLIB_H', 1) # are there systems without stdlib.h?
197 conf.define('STDC_HEADERS', 1) # an optimistic guess ;-)
198 _add_to_env_and_define(conf, 'HAVE_REGCOMP', 1) # needed for CTags
200 conf.check_cc(function_name='fgetpos', header_name='stdio.h', mandatory=False)
201 conf.check_cc(function_name='ftruncate', header_name='unistd.h', mandatory=False)
202 conf.check_cc(function_name='mkstemp', header_name='stdlib.h', mandatory=False)
203 conf.check_cc(function_name='strstr', header_name='string.h')
205 conf.check_cc(function_name='pow', header_name='math.h', lib='m', uselib_store='M')
207 # check sunOS socket support
208 if Options.platform == 'sunos':
209 conf.check_cc(function_name='socket', lib='socket',
210 header_name='sys/socket.h', uselib_store='SUNOS_SOCKET', mandatory=True)
212 # check for cxx after the header and function checks have been done to ensure they are
213 # checked with cc not cxx
214 conf.load('compiler_cxx')
217 _load_intltool_if_available(conf)
219 # GTK / GIO version check
220 gtk_package_name = 'gtk+-3.0' if conf.options.use_gtk3 else 'gtk+-2.0'
221 minimum_gtk_version = MINIMUM_GTK3_VERSION if conf.options.use_gtk3 else MINIMUM_GTK_VERSION
222 conf.check_cfg(package=gtk_package_name, atleast_version=minimum_gtk_version, uselib_store='GTK',
223 mandatory=True, args='--cflags --libs')
224 conf.check_cfg(package='glib-2.0', atleast_version=MINIMUM_GLIB_VERSION, uselib_store='GLIB',
225 mandatory=True, args='--cflags --libs')
226 conf.check_cfg(package='gmodule-2.0', uselib_store='GMODULE',
227 mandatory=True, args='--cflags --libs')
228 conf.check_cfg(package='gio-2.0', uselib_store='GIO', args='--cflags --libs', mandatory=True)
229 gtk_version = conf.check_cfg(modversion=gtk_package_name, uselib_store='GTK') or 'Unknown'
230 conf.check_cfg(package='gthread-2.0', uselib_store='GTHREAD', args='--cflags --libs')
231 # remember GTK version for the build step
232 conf.env['gtk_package_name'] = gtk_package_name
233 conf.env['minimum_gtk_version'] = minimum_gtk_version
234 conf.env['use_gtk3'] = conf.options.use_gtk3
236 revision = _get_git_rev(conf)
238 # rst2html for the HTML manual
239 if not conf.options.no_html_doc and revision is not None:
241 conf.env['RST2HTML'] = _find_rst2html(conf)
243 error_msg = '''Documentation enabled but rst2html not found.
244 You can explicitly disable building of the HTML manual with --disable-html-docs,
245 but you then may not have a local copy of the HTML manual.'''
246 raise WafError(error_msg)
250 if conf.env['PREFIX'].lower() == tempfile.gettempdir().lower():
251 # overwrite default prefix on Windows (tempfile.gettempdir() is the Waf default)
252 new_prefix = os.path.join(str(conf.root), '%s-%s' % (APPNAME, VERSION))
253 _add_to_env_and_define(conf, 'PREFIX', new_prefix, quote=True)
254 _add_to_env_and_define(conf, 'BINDIR', os.path.join(new_prefix, 'bin'), quote=True)
255 _add_to_env_and_define(conf, 'DOCDIR', os.path.join(conf.env['PREFIX'], 'doc'), quote=True)
256 _add_to_env_and_define(conf, 'LIBDIR', '%s/lib' % conf.env['PREFIX'], quote=True)
257 conf.define('LOCALEDIR', os.path.join('share' 'locale'), quote=True)
258 # overwrite LOCALEDIR to install message catalogues properly
259 conf.env['LOCALEDIR'] = os.path.join(conf.env['PREFIX'], 'share', 'locale')
260 # DATADIR is defined in objidl.h, so we remove it from config.h but keep it in env
261 conf.undefine('DATADIR')
262 conf.env['DATADIR'] = os.path.join(conf.env['PREFIX'], 'data')
263 conf.env.append_value('LINKFLAGS_cprogram', [
266 '-static-libstdc++'])
267 conf.env.append_value('LIB_WIN32', ['wsock32', 'uuid', 'ole32', 'iberty'])
269 conf.env['cshlib_PATTERN'] = '%s.so'
270 # DATADIR and LOCALEDIR are defined by the intltool tool
271 # but they are not added to the environment, so we need to
272 _add_define_to_env(conf, 'DATADIR')
273 _add_define_to_env(conf, 'LOCALEDIR')
274 docdir = os.path.join(conf.env['DATADIR'], 'doc', 'geany')
275 libdir = os.path.join(conf.env['PREFIX'], 'lib')
276 mandir = os.path.join(conf.env['DATADIR'], 'man')
277 _define_from_opt(conf, 'DOCDIR', conf.options.docdir, docdir)
278 _define_from_opt(conf, 'LIBDIR', conf.options.libdir, libdir)
279 _define_from_opt(conf, 'MANDIR', conf.options.mandir, mandir)
281 conf.define('ENABLE_NLS', 1)
282 conf.define('GEANY_LOCALEDIR', '' if is_win32 else conf.env['LOCALEDIR'], quote=True)
283 conf.define('GEANY_DATADIR', 'data' if is_win32 else conf.env['DATADIR'], quote=True)
284 conf.define('GEANY_DOCDIR', conf.env['DOCDIR'], quote=True)
285 conf.define('GEANY_LIBDIR', '' if is_win32 else conf.env['LIBDIR'], quote=True)
286 conf.define('GEANY_PREFIX', '' if is_win32 else conf.env['PREFIX'], quote=True)
287 conf.define('PACKAGE', APPNAME, quote=True)
288 conf.define('VERSION', VERSION, quote=True)
289 conf.define('REVISION', revision or '-1', quote=True)
291 conf.define('GETTEXT_PACKAGE', APPNAME, quote=True)
295 conf.options.no_vte = True
297 _define_from_opt(conf, 'HAVE_PLUGINS', not conf.options.no_plugins, None)
298 _define_from_opt(conf, 'HAVE_SOCKET', not conf.options.no_socket, None)
299 _define_from_opt(conf, 'HAVE_VTE', not conf.options.no_vte, None)
301 conf.write_config_header('config.h', remove=False)
303 # some more compiler flags
304 conf.env.append_value('CFLAGS', ['-DHAVE_CONFIG_H'])
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 = '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_file_entry.h tagmanager/src/tm_project.h
555 tagmanager/src/tm_source_file.h tagmanager/src/tm_parser.h
556 tagmanager/src/tm_symbol.h tagmanager/src/tm_tag.h
557 tagmanager/src/tm_tagmanager.h tagmanager/src/tm_work_object.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()