wscript: Bump jackdbus version to 2.23.2
[jackdbus.git] / wscript
blobcb734aa2c0ec346a6d5f8f030408c023f9fd24e1
1 #! /usr/bin/python3
2 # encoding: utf-8
4 # Copyright (C) 2015-2018 Karl Linden <karl.j.linden@gmail.com>
5 # Copyleft (C) 2008-2024 Nedko Arnaudov
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 from __future__ import print_function
23 import os
24 import shutil
25 import sys
26 import re
28 from waflib import Logs, Options, TaskGen
29 from waflib import Context
30 from waflib import Scripting
31 from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext
32 from waftoolchainflags import WafToolchainFlags
34 VERSION = "2.23.2"
35 APPNAME = 'jackdbus'
37 # these variables are mandatory ('/' are converted automatically)
38 top = '.'
39 out = 'build'
41 def display_feature(conf, msg, build):
42     if build:
43         conf.msg(msg, 'yes', color='GREEN')
44     else:
45         conf.msg(msg, 'no', color='YELLOW')
48 def options(opt):
49     # options provided by the modules
50     opt.load('compiler_c')
51     opt.load('autooptions')
53     # install directories
54     opt.add_option(
55         '--htmldir',
56         default=None,
57         help='HTML documentation directory [Default: <prefix>/share/jack-audio-connection-kit/reference/html/',
58     )
59     opt.add_option('--libdir', help='Library directory [Default: <prefix>/lib]')
60     opt.add_option('--pkgconfigdir', help='pkg-config file directory [Default: <libdir>/pkgconfig]')
61     opt.add_option('--mandir', help='Manpage directory [Default: <prefix>/share/man/man1]')
63     # options affecting binaries
64     opt.add_option(
65         '--platform',
66         default=sys.platform,
67         help='Target platform for cross-compiling, e.g. cygwin or win32',
68     )
69     opt.add_auto_option(
70         'devmode',
71         help='Enable devmode', # enable warnings and treat them as errors
72         conf_dest='BUILD_DEVMODE',
73         default=False,
74     )
75     opt.add_option('--debug', action='store_true', default=False, dest='debug', help='Build debuggable binaries')
76     opt.add_option('--siginfo', action='store_true', default=False, dest='siginfo', help="Log backtrace on fatal signal")
77     opt.add_option('--distname', default=None, help="Name for the distribution tarball")
78     opt.add_option('--distsuffix', default="", help="String to append to the distribution tarball name")
79 #    opt.add_option('--tagdist', action='store_true', default=False, help='Create of git tag for distname')
81     #opt.set_auto_options_define('HAVE_%s')
82     #opt.set_auto_options_style('yesno_and_hack')
84     # options with third party dependencies
85     #doxygen = opt.add_auto_option(
86     #        'doxygen',
87     #        help='Build doxygen documentation',
88     #        conf_dest='BUILD_DOXYGEN_DOCS',
89     #        default=False)
90     #doxygen.find_program('doxygen')
92     # dbus options
93     opt.recurse('dbus')
95     # this must be called before the configure phase
96     #opt.apply_auto_options_hack()
99 def detect_platform(conf):
100     # GNU/kFreeBSD and GNU/Hurd are treated as Linux
101     platforms = [
102         # ('KEY, 'Human readable name', ['strings', 'to', 'check', 'for'])
103         ('IS_LINUX',   'Linux',   ['gnu0', 'gnukfreebsd', 'linux', 'posix']),
104         ('IS_FREEBSD', 'FreeBSD', ['freebsd']),
105         ('IS_SUN',     'SunOS',   ['sunos']),
106     ]
108     for key, name, strings in platforms:
109         conf.env[key] = False
111     conf.start_msg('Checking platform')
112     platform = Options.options.platform
113     for key, name, strings in platforms:
114         for s in strings:
115             if platform.startswith(s):
116                 conf.env[key] = True
117                 conf.end_msg(name, color='CYAN')
118                 break
120 def configure(conf):
121     conf.load('compiler_c')
123     detect_platform(conf)
124     flags = WafToolchainFlags(conf)
126     conf.check_cfg(package='jackserver', uselib_store='JACKSERVER', args=["--cflags", "--libs"])
128     conf.check_cfg(package='expat', args='--cflags --libs')
130     flags.add_c('-Wall')
132     if conf.env['IS_FREEBSD']:
133         conf.check(lib='execinfo', uselib='EXECINFO', define_name='EXECINFO')
134         conf.check_cfg(package='libsysinfo', args='--cflags --libs')
136     conf.load('autooptions')
138     conf.env['LIB_PTHREAD'] = ['pthread']
139     conf.env['LIB_DL'] = ['dl']
140     conf.env['LIB_RT'] = ['rt']
141     conf.env['LIB_M'] = ['m']
142     conf.env['JACK_VERSION'] = VERSION
144     conf.env['BINDIR'] = conf.env['PREFIX'] + '/bin'
146     if Options.options.htmldir:
147         conf.env['HTMLDIR'] = Options.options.htmldir
148     else:
149         # set to None here so that the doxygen code can find out the highest
150         # directory to remove upon install
151         conf.env['HTMLDIR'] = None
153     if Options.options.libdir:
154         conf.env['LIBDIR'] = Options.options.libdir
155     else:
156         conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib'
158     if Options.options.pkgconfigdir:
159         conf.env['PKGCONFDIR'] = Options.options.pkgconfigdir
160     else:
161         conf.env['PKGCONFDIR'] = conf.env['LIBDIR'] + '/pkgconfig'
163     if Options.options.mandir:
164         conf.env['MANDIR'] = Options.options.mandir
165     else:
166         conf.env['MANDIR'] = conf.env['PREFIX'] + '/share/man/man1'
168     flags.add_c('-std=gnu99')
169     if conf.env['BUILD_DEVMODE']:
170         flags.add_c(['-Wall', '-Wextra'])
171         #flags.add_c('-Wpedantic')
172         flags.add_c('-Werror')
173         flags.add_c(['-Wno-variadic-macros', '-Wno-gnu-zero-variadic-macro-arguments'])
175         # https://wiki.gentoo.org/wiki/Modern_C_porting
176         if conf.env['CC'] == 'clang':
177             flags.add_c('-Wno-unknown-argumemt')
178             flags.add_c('-Werror=implicit-function-declaration')
179             flags.add_c('-Werror=incompatible-function-pointer-types')
180             flags.add_c('-Werror=deprecated-non-prototype')
181             flags.add_c('-Werror=strict-prototypes')
182             if int(conf.env['CC_VERSION'][0]) < 16:
183                 flags.add_c('-Werror=implicit-int')
184         else:
185             flags.add_c('-Wno-unknown-warning-option')
186             flags.add_c('-Werror=implicit-function-declaration')
187             flags.add_c('-Werror=implicit-int')
188             flags.add_c('-Werror=incompatible-pointer-types')
189             flags.add_c('-Werror=strict-prototypes')
190     if conf.env['BUILD_DEBUG']:
191         flags.add_c(['-O0', '-g', '-fno-omit-frame-pointer'])
192         flags.add_link('-g')
194     conf.env['BUILD_SIGINFO'] =  Options.options.siginfo
196     conf.define('JACK_VERSION', conf.env['JACK_VERSION'])
197     conf.define('SIGINFO_ENABLED', conf.env['BUILD_SIGINFO'])
198     conf.write_config_header('config.h', remove=False)
200     conf.recurse('dbus')
202     flags.flush()
204     print()
205     version_msg = APPNAME + "-" + VERSION
206     if os.access('version.h', os.R_OK):
207         data = open('version.h').read()
208         m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
209         if m != None:
210             version_msg += " exported from " + m.group(1)
211     elif os.access('.git', os.R_OK):
212         version_msg += " git revision will be checked and eventually updated during build"
213     print(version_msg)
215     conf.msg('Install prefix', conf.env['PREFIX'], color='CYAN')
216     conf.msg('Library directory', conf.all_envs['']['LIBDIR'], color='CYAN')
217     display_feature(conf, 'Build debuggable binaries', conf.env['BUILD_DEBUG'])
218     display_feature(conf, 'Build with siginfo', conf.env['BUILD_SIGINFO'])
220     tool_flags = [
221         ('C compiler flags',   ['CFLAGS', 'CPPFLAGS']),
222         ('Linker flags',       ['LINKFLAGS', 'LDFLAGS'])
223     ]
224     for name, vars in tool_flags:
225         flags = []
226         for var in vars:
227             flags += conf.all_envs[''][var]
228         conf.msg(name, repr(flags), color='NORMAL')
230     #conf.summarize_auto_options()
232     conf.msg('D-Bus service install directory', conf.env['DBUS_SERVICES_DIR'], color='CYAN')
234     if conf.env['DBUS_SERVICES_DIR'] != conf.env['DBUS_SERVICES_DIR_REAL']:
235         print()
236         print(Logs.colors.RED + 'WARNING: D-Bus session services directory as reported by pkg-config is')
237         print(Logs.colors.RED + 'WARNING:', end=' ')
238         print(Logs.colors.CYAN + conf.env['DBUS_SERVICES_DIR_REAL'])
239         print(Logs.colors.RED + 'WARNING: but service file will be installed in')
240         print(Logs.colors.RED + 'WARNING:', end=' ')
241         print(Logs.colors.CYAN + conf.env['DBUS_SERVICES_DIR'])
242         print(
243             Logs.colors.RED + 'WARNING: You may need to adjust your D-Bus configuration after installing jackdbus'
244             )
245         print('WARNING: You can override dbus service install directory')
246         print('WARNING: with --enable-pkg-config-dbus-service-dir option to this script')
247         print(Logs.colors.NORMAL, end=' ')
248     print()
250 def git_ver(self):
251     bld = self.generator.bld
252     header = self.outputs[0].abspath()
253     if os.access('./version.h', os.R_OK):
254         header = os.path.join(os.getcwd(), out, "version.h")
255         shutil.copy('./version.h', header)
256         data = open(header).read()
257         m = re.match(r'^#define GIT_VERSION "([^"]*)"$', data)
258         if m != None:
259             self.ver = m.group(1)
260             Logs.pprint('BLUE', "tarball from git revision " + self.ver)
261         else:
262             self.ver = "tarball"
263         return
265     if bld.srcnode.find_node('.git'):
266         self.ver = bld.cmd_and_log("LANG= git rev-parse HEAD", quiet=Context.BOTH).splitlines()[0]
267         if bld.cmd_and_log("LANG= git diff-index --name-only HEAD", quiet=Context.BOTH).splitlines():
268             self.ver += "-dirty"
270         Logs.pprint('BLUE', "git revision " + self.ver)
271     else:
272         self.ver = "unknown"
274     fi = open(header, 'w')
275     fi.write('#define GIT_VERSION "%s"\n' % self.ver)
276     fi.close()
278 def build(bld):
279     bld(rule=git_ver, target='version.h', update_outputs=True, always=True, ext_out=['.h'])
281     # process subfolders from here
283     if bld.env['IS_LINUX'] or bld.env['IS_FREEBSD']:
284         bld.recurse('man')
285     bld.recurse('dbus')
287     if bld.env['BUILD_DOXYGEN_DOCS']:
288         html_build_dir = bld.path.find_or_declare('html').abspath()
290         bld(
291             features='subst',
292             source='doxyfile.in',
293             target='doxyfile',
294             HTML_BUILD_DIR=html_build_dir,
295             SRCDIR=bld.srcnode.abspath(),
296             VERSION=VERSION
297         )
299         # There are two reasons for logging to doxygen.log and using it as
300         # target in the build rule (rather than html_build_dir):
301         # (1) reduce the noise when running the build
302         # (2) waf has a regular file to check for a timestamp. If the directory
303         #     is used instead waf will rebuild the doxygen target (even upon
304         #     install).
305         def doxygen(task):
306             doxyfile = task.inputs[0].abspath()
307             logfile = task.outputs[0].abspath()
308             cmd = '%s %s &> %s' % (task.env['DOXYGEN'][0], doxyfile, logfile)
309             return task.exec_command(cmd)
311         bld(
312             rule=doxygen,
313             source='doxyfile',
314             target='doxygen.log'
315         )
317         # Determine where to install HTML documentation. Since share_dir is the
318         # highest directory the uninstall routine should remove, there is no
319         # better candidate for share_dir, but the requested HTML directory if
320         # --htmldir is given.
321         if bld.env['HTMLDIR']:
322             html_install_dir = bld.options.destdir + bld.env['HTMLDIR']
323             share_dir = html_install_dir
324         else:
325             share_dir = bld.options.destdir + bld.env['PREFIX'] + '/share/jack-audio-connection-kit'
326             html_install_dir = share_dir + '/reference/html/'
328         if bld.cmd == 'install':
329             if os.path.isdir(html_install_dir):
330                 Logs.pprint('CYAN', 'Removing old doxygen documentation installation...')
331                 shutil.rmtree(html_install_dir)
332                 Logs.pprint('CYAN', 'Removing old doxygen documentation installation done.')
333             Logs.pprint('CYAN', 'Installing doxygen documentation...')
334             shutil.copytree(html_build_dir, html_install_dir)
335             Logs.pprint('CYAN', 'Installing doxygen documentation done.')
336         elif bld.cmd == 'uninstall':
337             Logs.pprint('CYAN', 'Uninstalling doxygen documentation...')
338             if os.path.isdir(share_dir):
339                 shutil.rmtree(share_dir)
340             Logs.pprint('CYAN', 'Uninstalling doxygen documentation done.')
341         elif bld.cmd == 'clean':
342             if os.access(html_build_dir, os.R_OK):
343                 Logs.pprint('CYAN', 'Removing doxygen generated documentation...')
344                 shutil.rmtree(html_build_dir)
345                 Logs.pprint('CYAN', 'Removing doxygen generated documentation done.')
347 class jackdbus_dist(Scripting.Dist):
348     cmd = 'dist'
349     fun = 'dist'
351     def __init__(self):
352         Scripting.Dist.__init__(self)
353         if Options.options.distname:
354             self.base_name = Options.options.distname
355             self.tag_name = Options.options.distname
356         else:
357             self.tag_name = VERSION
358             try:
359                 sha = self.cmd_and_log("LANG= git rev-parse --short HEAD", quiet=Context.BOTH).splitlines()[0]
360                 self.base_name = APPNAME + '-' + VERSION + "-g" + sha
361             except:
362                 self.base_name = APPNAME + '-' + VERSION
363         self.base_name += Options.options.distsuffix
365         #print self.base_name
367 #        if Options.options.tagdist:
368         ret = self.exec_command("LANG= git tag " + self.tag_name)
369         if ret != 0:
370             raise waflib.Errors.WafError('git tag creation failed')
372     def get_base_name(self):
373         return self.base_name
375     def get_excl(self):
376         excl = Scripting.Dist.get_excl(self)
378         excl += ' .gitmodules'
380         excl += ' .github'
381         excl += ' .flake8'
382         excl += ' .cirrus.yml'
383         excl += ' .wafupdaterc'
385         excl += ' README-docinfo-header.html'
386         excl += ' README-docinfo.html'
388         excl += ' GTAGS'
389         excl += ' GRTAGS'
390         excl += ' GPATH'
391         excl += ' GSYMS'
393         excl += ' jack2'
395         #print repr(excl)
396         return excl
398     def execute(self):
399         shutil.copy('./build/version.h', "./")
400         try:
401             super(jackdbus_dist, self).execute()
402         finally:
403             os.remove("version.h")