From: Paul Brossier Date: Wed, 23 Sep 2009 17:47:16 +0000 (+0200) Subject: use waf as new build system X-Git-Tag: bzr2git~329 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=000b0903393a05eceb0f62c92ed7edf5f070ca52;p=aubio.git use waf as new build system --- diff --git a/cpp/wscript_build b/cpp/wscript_build new file mode 100644 index 00000000..6d7a4661 --- /dev/null +++ b/cpp/wscript_build @@ -0,0 +1,11 @@ +# build libaubiocpp +libaubiocpp = bld.new_task_gen( + features = 'cxx cshlib', + includes = ['.', '../src'], + source = bld.path.ant_glob('*.cpp'), + target = 'aubiocpp', + uselib_local = ['aubio'], + vnum = bld.env['LIB_VERSION']) + +# install header +bld.install_files('${PREFIX}/include/aubio/', 'aubiocpp.h') diff --git a/examples/wscript_build b/examples/wscript_build new file mode 100644 index 00000000..7b00b37a --- /dev/null +++ b/examples/wscript_build @@ -0,0 +1,16 @@ +# build examples + +# loop over all *.c filenames in examples to build them all +for target_name in bld.path.ant_glob('*.c').split(): + # ignore aubioonset.c and utils.c + if target_name in ['utils.c']: continue + this_target = bld.new_task_gen(features = 'cc cprogram') + this_target.includes = '. ../src ../ext' + this_target.uselib = ['LASH'] + this_target.uselib_local = ['aubio', 'aubioext'] + this_target.defines = ['AUBIO_PREFIX="' + bld.env['AUBIO_PREFIX'] + '"'] + this_target.defines += ['PACKAGE="' + bld.env['PACKAGE'] + '"'] + # add utils.c as source file + this_target.source = [target_name, 'utils.c'] + # program name is filename.c without the .c + this_target.target = target_name.split('.')[0] diff --git a/ext/wscript_build b/ext/wscript_build new file mode 100644 index 00000000..a4da40e9 --- /dev/null +++ b/ext/wscript_build @@ -0,0 +1,13 @@ +# build libaubioext +libaubioext = bld.new_task_gen( + features = 'cc cshlib', + includes = ['.', '../src'], + source = bld.path.ant_glob('*.c **/*.c'), + target = 'aubioext', + uselib = ['ALSA', 'SNDFILE', 'JACK'], + uselib_local = ['aubio'], + vnum = bld.env['LIB_VERSION']) + +# install headers +for file in bld.path.ant_glob('**/*.h').split(): + bld.install_as('${PREFIX}/include/aubio/' + file, file) diff --git a/plugins/puredata/wscript_build b/plugins/puredata/wscript_build new file mode 100644 index 00000000..c87b4386 --- /dev/null +++ b/plugins/puredata/wscript_build @@ -0,0 +1,35 @@ +# build puredata external + +aubio_pd = bld.new_task_gen( + features = 'cc cshlib', + includes = '../../src', + uselib_local = ['aubio'], + defines = ['PD'], + install_path = '${PREFIX}/lib/pd/extra') + +# copy environment to tweak only pd stuff +aubio_pd.env = bld.env.copy() +aubio_pd.env.detach() + +if bld.env['DEST_OS'] == 'win32': + aubio_pd.target = 'aubio.dll' + # do not use -fPIC -DPIC on windows + aubio_pd.env.shlib_CCFLAGS.remove('-fPIC') + aubio_pd.env.shlib_CCFLAGS.remove('-DPIC') + aubio_pd.env.append_unique('shlib_LINKFLAGS', ['-export_dynamic', '-lpd']) +elif bld.env['DEST_OS'] == 'darwin': + aubio_pd.target = 'aubio.pd_darwin' + aubio_pd.env.append_unique('shlib_LINKFLAGS', + ['-bundle', '-undefined suppres', '-flat_namespace']) +else: #if bld.env['DEST_OS'] == 'linux': + aubio_pd.target = 'aubio.pd_linux' + aubio_pd.env.append_unique('shlib_LINKFLAGS', ['--export_dynamic']) + +# do not rename the shlib at all +aubio_pd.env.shlib_PATTERN = '%s' +# get the source files +aubio_pd.find_sources_in_dirs('.') + +bld.install_files('${PREFIX}/lib/pd/doc/5.reference', 'help/*.pd') + +bld.install_files('${PREFIX}/lib/pd/doc/aubio', 'examples/*.pd') diff --git a/python/aubio/wscript_build b/python/aubio/wscript_build new file mode 100644 index 00000000..61c36d22 --- /dev/null +++ b/python/aubio/wscript_build @@ -0,0 +1,14 @@ +pyaubio = bld.new_task_gen(name = 'python-aubio', + features = 'cc cshlib pyext', + source = '../../swig/aubio.i', + target = '_aubiowrapper', + uselib_local = ['aubio', 'aubioext'], + swig_flags = '-python -Wall', + includes = '. ../../src ../../ext') +pyaubio.install_path = '${PYTHONDIR}/${PACKAGE}' + +# install python files +for file in bld.path.ant_glob('**/*.py').split(): + bld.install_as('${PYTHONDIR}/${PACKAGE}/' + file, file) +# install swig generated python file +bld.install_files('${PYTHONDIR}/${PACKAGE}/', '../../swig/aubiowrapper.py') diff --git a/python/wscript_build b/python/wscript_build new file mode 100644 index 00000000..ad1445be --- /dev/null +++ b/python/wscript_build @@ -0,0 +1,3 @@ +# install headers +for file in ['aubiocut', 'aubiopitch']: + bld.install_as('${PREFIX}/bin/' + file, file, chmod = 0755) diff --git a/src/wscript_build b/src/wscript_build new file mode 100644 index 00000000..e88e0631 --- /dev/null +++ b/src/wscript_build @@ -0,0 +1,13 @@ +# build libaubio +libaubio = bld.new_task_gen( + features = 'cc cshlib', + includes = ['.'], + source = bld.path.ant_glob('*.c **/*.c'), + target = 'aubio', + uselib = ['FFTW3', 'FFTW3F', 'SAMPLERATE'], + vnum = bld.env['LIB_VERSION']) + +# install headers, except _priv.h ones +for file in bld.path.ant_glob('**/*.h').split(): + if '_priv.h' in file: continue + bld.install_as('${PREFIX}/include/aubio/' + file, file) diff --git a/swig/swig.py b/swig/swig.py new file mode 100644 index 00000000..c3f5cfbc --- /dev/null +++ b/swig/swig.py @@ -0,0 +1,170 @@ +#! /usr/bin/env python +# encoding: UTF-8 +# Petar Forai +# Thomas Nagy 2008 + +import re +import Task, Utils, Logs +from TaskGen import extension +from Configure import conf +import preproc + +SWIG_EXTS = ['.swig', '.i'] + +swig_str = '${SWIG} ${SWIGFLAGS} ${SRC}' +cls = Task.simple_task_type('swig', swig_str, color='BLUE', before='cc cxx') + +re_module = re.compile('%module(?:\s*\(.*\))?\s+(.+)', re.M) + +re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M) +re_2 = re.compile('%include "(.*)"', re.M) +re_3 = re.compile('#include "(.*)"', re.M) + +def scan(self): + "scan for swig dependencies, climb the .i files" + env = self.env + + lst_src = [] + + seen = [] + to_see = [self.inputs[0]] + + while to_see: + node = to_see.pop(0) + if node.id in seen: + continue + seen.append(node.id) + lst_src.append(node) + + # read the file + code = node.read(env) + code = preproc.re_nl.sub('', code) + code = preproc.re_cpp.sub(preproc.repl, code) + + # find .i files and project headers + names = re_2.findall(code) + re_3.findall(code) + for n in names: + for d in self.generator.swig_dir_nodes + [node.parent]: + u = d.find_resource(n) + if u: + to_see.append(u) + break + else: + Logs.warn('could not find %r' % n) + + # list of nodes this one depends on, and module name if present + if Logs.verbose: + Logs.debug('deps: deps for %s: %s' % (str(self), str(lst_src))) + return (lst_src, []) +cls.scan = scan + +# provide additional language processing +swig_langs = {} +def swig(fun): + swig_langs[fun.__name__.replace('swig_', '')] = fun + +@swig +def swig_python(tsk): + tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.py')) + +@swig +def swig_ocaml(tsk): + tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.ml')) + tsk.set_outputs(tsk.inputs[0].parent.find_or_declare(tsk.module + '.mli')) + +def add_swig_paths(self): + if getattr(self, 'add_swig_paths_done', None): + return + self.add_swig_paths_done = True + + self.swig_dir_nodes = [] + for x in self.to_list(self.includes): + node = self.path.find_dir(x) + if not node: + Logs.warn('could not find the include %r' % x) + continue + self.swig_dir_nodes.append(node) + + # add the top-level, it is likely to be added + self.swig_dir_nodes.append(self.bld.srcnode) + for x in self.swig_dir_nodes: + self.env.append_unique('SWIGFLAGS', '-I%s' % x.abspath(self.env)) # build dir + self.env.append_unique('SWIGFLAGS', '-I%s' % x.abspath()) # source dir + +@extension(SWIG_EXTS) +def i_file(self, node): + flags = self.to_list(getattr(self, 'swig_flags', [])) + + ext = '.swigwrap_%d.c' % self.idx + if '-c++' in flags: + ext += 'xx' + + # the user might specify the module directly + module = getattr(self, 'swig_module', None) + if not module: + # else, open the files and search + txt = node.read(self.env) + m = re_module.search(txt) + if not m: + raise "for now we are expecting a module name in the main swig file" + module = m.group(1) + out_node = node.parent.find_or_declare(module + ext) + + # the task instance + tsk = self.create_task('swig') + tsk.set_inputs(node) + tsk.set_outputs(out_node) + tsk.module = module + tsk.env['SWIGFLAGS'] = flags + + if not '-outdir' in flags: + flags.append('-outdir') + flags.append(node.parent.abspath(self.env)) + + if not '-o' in flags: + flags.append('-o') + flags.append(out_node.abspath(self.env)) + + # add the language-specific output files as nodes + # call funs in the dict swig_langs + for x in flags: + # obtain the language + x = x[1:] + try: + fun = swig_langs[x] + except KeyError: + pass + else: + fun(tsk) + + self.allnodes.append(out_node) + + add_swig_paths(self) + +@conf +def check_swig_version(conf, minver=None): + """Check for a minimum swig version like conf.check_swig_version('1.3.28') + or conf.check_swig_version((1,3,28)) """ + reg_swig = re.compile(r'SWIG Version\s(.*)', re.M) + + swig_out = Utils.cmd_output('%s -version' % conf.env['SWIG']) + + swigver = [int(s) for s in reg_swig.findall(swig_out)[0].split('.')] + if isinstance(minver, basestring): + minver = [int(s) for s in minver.split(".")] + if isinstance(minver, tuple): + minver = [int(s) for s in minver] + result = (minver is None) or (minver[:3] <= swigver[:3]) + swigver_full = '.'.join(map(str, swigver)) + if result: + conf.env['SWIG_VERSION'] = swigver_full + minver_str = '.'.join(map(str, minver)) + if minver is None: + conf.check_message_custom('swig version', '', swigver_full) + else: + conf.check_message('swig version', '>= %s' % (minver_str,), result, option=swigver_full) + return result + +def detect(conf): + swig = conf.find_program('swig', var='SWIG', mandatory=True) + diff --git a/wscript b/wscript new file mode 100644 index 00000000..9eff5cad --- /dev/null +++ b/wscript @@ -0,0 +1,163 @@ +# TODO +# - plugins/puredata: add pd compilation +# - java: add swig compilation +# - doc: add docbook2html and doxygen +# - tests: move to new unit test system + +APPNAME = 'aubio' +VERSION = '0.3.3' +LIB_VERSION = '2.1.1' +srcdir = '.' +blddir = 'build' + +import UnitTest + +def init(opt): + pass + +def set_options(opt): + opt.add_option('--disable-fftw3f', action='store_true', default=False, + help='compile with fftw3 instead of fftw3f') + opt.add_option('--disable-complex', action='store_true', default=False, + help='compile without C99 complex') + opt.add_option('--disable-jack', action='store_true', default=False, + help='compile without jack support') + opt.add_option('--disable-alsa', action='store_true', default=False, + help='compile without alsa support') + opt.add_option('--disable-lash', action='store_true', default=False, + help='compile without lash support') + opt.add_option('--enable-java', action='store_true', default=False, + help='compile with java support') + opt.tool_options('compiler_cc') + opt.tool_options('compiler_cxx') + opt.tool_options('gnu_dirs') + #opt.tool_options('UnitTest') + +def configure(conf): + import Options + conf.check_tool('compiler_cc') + conf.check_tool('compiler_cxx') + conf.check_tool('gnu_dirs') # helpful for autotools transition and .pc generation + conf.check_tool('misc') # needed for subst + + # check for required headers + conf.check(header_name='stdlib.h') + conf.check(header_name='stdio.h') + conf.check(header_name='math.h') + conf.check(header_name='string.h') + + # optionally use complex.h + if (Options.options.disable_complex == False): + conf.check(header_name='complex.h') + + # required dependancies + conf.check_cfg(package = 'sndfile', atleast_version = '1.0.4', + args = '--cflags --libs') + conf.check_cfg(package = 'samplerate', atleast_version = '0.0.15', + args = '--cflags --libs') + + # one of fftwf or fftw3f + if (Options.options.disable_fftw3f == True): + conf.check_cfg(package = 'fftw3', atleast_version = '3.0.0', + args = '--cflags --libs') + else: + conf.check_cfg(package = 'fftw3f', atleast_version = '3.0.0', + args = '--cflags --libs') + + # optional dependancies + if (Options.options.disable_jack == False): + conf.check_cfg(package = 'jack', atleast_version = '0.15.0', + args = '--cflags --libs') + if (Options.options.disable_alsa == False): + conf.check_cfg(package = 'alsa', atleast_version = '0.0.9', + args = '--cflags --libs') + if (Options.options.disable_lash == False): + conf.check_cfg(package = 'lash-1.0', atleast_version = '0.5.0', + args = '--cflags --libs', uselib_store = 'LASH') + + # swig + if conf.find_program('swig', var='SWIG', mandatory = False): + conf.check_tool('swig', tooldir='swig') + conf.check_swig_version('1.3.27') + + # python + if conf.find_program('python', mandatory = False): + conf.check_tool('python') + conf.check_python_version((2,4,2)) + conf.check_python_headers() + + # java + if (Options.options.enable_java == True): + conf.fatal('Java build not yet implemented') + conf.check_tool('java') + + # check support for C99 __VA_ARGS__ macros + check_c99_varargs = ''' +#include +#define AUBIO_ERR(...) fprintf(stderr, __VA_ARGS__) +''' + if conf.check_cc(fragment = check_c99_varargs, + type='cstaticlib', + msg = 'Checking for C99 __VA_ARGS__ macro'): + conf.define('HAVE_C99_VARARGS_MACROS', 1) + + # write configuration header + conf.write_config_header('src/config.h') + + # check for puredata header + conf.check(header_name='m_pd.h') + + # add some defines used in examples + conf.define('AUBIO_PREFIX', conf.env['PREFIX']) + conf.define('PACKAGE', APPNAME) + + # check if docbook-to-man is installed, optional + conf.find_program('docbook-to-man', var='DOCBOOKTOMAN', mandatory=False) + +def build(bld): + bld.env['VERSION'] = VERSION + bld.env['LIB_VERSION'] = LIB_VERSION + + # add sub directories + bld.add_subdirs('src ext examples cpp tests/src') + if bld.env['SWIG']: + if bld.env['PYTHON']: + bld.add_subdirs('python/aubio python') + if bld.env['JAVA']: + pass + + # create the aubio.pc file for pkg-config + aubiopc = bld.new_task_gen('subst') + aubiopc.source = 'aubio.pc.in' + aubiopc.target = 'aubio.pc' + aubiopc.install_path = '${PREFIX}/lib/pkgconfig' + + # build manpages from sgml files + if bld.env['DOCBOOKTOMAN']: + import TaskGen + TaskGen.declare_chain( + name = 'docbooktoman', + rule = '${DOCBOOKTOMAN} ${SRC} > ${TGT}', + ext_in = '.sgml', + ext_out = '.1', + reentrant = 0, + ) + manpages = bld.new_task_gen(name = 'docbooktoman', + source=bld.path.ant_glob('doc/*.sgml')) + bld.install_files('${MANDIR}/man1', bld.path.ant_glob('doc/*.1')) + + if bld.env['HAVE_M_PD_H']: + bld.add_subdirs('plugins/puredata') + + # install woodblock sound + bld.install_files('${PREFIX}/share/sounds/aubio/', + 'sounds/woodblock.aiff') + +def shutdown(bld): + pass + +def check(bld): + ut = UnitTest.unit_test() + ut.change_to_testfile_dir = True + ut.run() + ut.print_results()