import os
import subprocess
import sys
+import shutil
from waflib import Configure, Context, Logs, Node, Options, Task, Utils
from waflib.TaskGen import feature, before, after
opt.add_option('--docs', action='store_true', default=False, dest='docs',
help="Build documentation - requires doxygen")
- # LV2 options
- opt.add_option('--lv2-user', action='store_true', default=False, dest='lv2_user',
- help="Install LV2 bundles to user location")
- opt.add_option('--lv2-system', action='store_true', default=False, dest='lv2_system',
- help="Install LV2 bundles to system location")
- dirs_options.add_option('--lv2dir', type='string',
- help="LV2 bundles [Default: LIBDIR/lv2]")
g_step = 1
+def copyfile (task):
+ # a cross-platform utility for copying files as part of tasks
+ src = task.inputs[0].abspath()
+ tgt = task.outputs[0].abspath()
+ shutil.copy2 (src, tgt)
+
def check_header(conf, lang, name, define='', mandatory=True):
"Check for a header"
includes = '' # search default system include paths
else:
return os.path.normpath(path)
+def ensure_visible_symbols(bld, visible):
+ if bld.env['MSVC_COMPILER']:
+ if visible:
+ print ('*** WARNING: MSVC does not allow symbols to be visible/exported by default while building ' + bld.name)
+ else:
+ pass
+ else:
+ if not hasattr (bld,'cxxflags'):
+ bld.cxxflags = []
+ if not hasattr (bld,'cflags'):
+ bld.cflags = []
+ if visible:
+ bld.cxxflags += [ '-fvisibility=default' ]
+ bld.cflags += [ '-fvisibility=default' ]
+ else:
+ bld.cxxflags += [ '-fvisibility=hidden' ]
+ bld.cflags += [ '-fvisibility=hidden' ]
+
+def set_basic_compiler_flags(conf, flag_dict):
+ if Options.options.debug:
+ conf.env.append_value('CFLAGS', flag_dict['debuggable'])
+ conf.env.append_value('CXXFLAGS', flag_dict['debuggable'])
+ conf.env.append_value('LINKFLAGS', flag_dict['linker-debuggable'])
+ else:
+ conf.env.append_value('CFLAGS', flag_dict['nondebuggable'])
+ conf.env.append_value('CXXFLAGS', flag_dict['nondebuggable'])
+
+ if Options.options.ultra_strict:
+ Options.options.strict = True
+ conf.env.append_value('CFLAGS', flag_dict['ultra-strict'])
+
+ if Options.options.strict:
+ conf.env.append_value('CFLAGS', flag_dict['c-strict'])
+ conf.env.append_value('CXXFLAGS', flag_dict['cxx-strict'])
+ conf.env.append_value('CFLAGS', flag_dict['strict'])
+ conf.env.append_value('CXXFLAGS', flag_dict['strict'])
+
+ conf.env.append_value('CFLAGS', flag_dict['show-column'])
+ conf.env.append_value('CXXFLAGS', flag_dict['show-column'])
+
def configure(conf):
global g_step
if g_step > 1:
return
- def append_cxx_flags(flags):
- conf.env.append_value('CFLAGS', flags)
- conf.env.append_value('CXXFLAGS', flags)
print('')
display_header('Global Configuration')
config_dir('MANDIR', opts.mandir, os.path.join(conf.env['DATADIR'], 'man'))
config_dir('DOCDIR', opts.docdir, os.path.join(conf.env['DATADIR'], 'doc'))
- if Options.options.lv2dir:
- conf.env['LV2DIR'] = Options.options.lv2dir
- elif Options.options.lv2_user:
- if sys.platform == "darwin":
- conf.env['LV2DIR'] = os.path.join(os.getenv('HOME'), 'Library/Audio/Plug-Ins/LV2')
- elif sys.platform == "win32":
- conf.env['LV2DIR'] = os.path.join(os.getenv('APPDATA'), 'LV2')
- else:
- conf.env['LV2DIR'] = os.path.join(os.getenv('HOME'), '.lv2')
- elif Options.options.lv2_system:
- if sys.platform == "darwin":
- conf.env['LV2DIR'] = '/Library/Audio/Plug-Ins/LV2'
- elif sys.platform == "win32":
- conf.env['LV2DIR'] = os.path.join(os.getenv('COMMONPROGRAMFILES'), 'LV2')
- else:
- conf.env['LV2DIR'] = os.path.join(conf.env['LIBDIR'], 'lv2')
- else:
- conf.env['LV2DIR'] = os.path.join(conf.env['LIBDIR'], 'lv2')
-
- conf.env['LV2DIR'] = normpath(conf.env['LV2DIR'])
-
if Options.options.docs:
doxygen = conf.find_program('doxygen')
if not doxygen:
if not dot:
conf.fatal("Graphviz (dot) is required to build with --docs")
- if Options.options.debug:
- if conf.env['MSVC_COMPILER']:
- conf.env['CFLAGS'] = ['/Od', '/Zi', '/MTd']
- conf.env['CXXFLAGS'] = ['/Od', '/Zi', '/MTd']
- conf.env['LINKFLAGS'] = ['/DEBUG']
- else:
- conf.env['CFLAGS'] = ['-O0', '-g']
- conf.env['CXXFLAGS'] = ['-O0', '-g']
- else:
- if conf.env['MSVC_COMPILER']:
- conf.env['CFLAGS'] = ['/MD']
- conf.env['CXXFLAGS'] = ['/MD']
- append_cxx_flags(['-DNDEBUG'])
-
- if Options.options.ultra_strict:
- Options.options.strict = True
- conf.env.append_value('CFLAGS', ['-Wredundant-decls',
- '-Wstrict-prototypes',
- '-Wmissing-prototypes'])
-
- if Options.options.strict:
- conf.env.append_value('CFLAGS', ['-std=c99', '-pedantic', '-Wshadow'])
- conf.env.append_value('CXXFLAGS', ['-ansi',
- '-Wnon-virtual-dtor',
- '-Woverloaded-virtual'])
- append_cxx_flags(['-Wall',
- '-Wcast-align',
- '-Wextra',
- '-Wwrite-strings'])
- if sys.platform != "darwin":
- # this is really only to be avoid on OLD apple gcc, but not sure how to version check
- append_cxx_flags(['-fstrict-overflow'])
-
- if not conf.check_cc(fragment = '''
-#ifndef __clang__
-#error
-#endif
-int main() { return 0; }''',
- features = 'c',
- mandatory = False,
- execute = False,
- msg = 'Checking for clang'):
- if sys.platform != "darwin":
- # this is really only to be avoid on OLD apple gcc, but not sure how to version check
- append_cxx_flags(['-Wunsafe-loop-optimizations'])
- # this is invalid (still) on Lion apple gcc
- append_cxx_flags(['-Wlogical-op'])
-
-
- if not conf.env['MSVC_COMPILER']:
- append_cxx_flags(['-fshow-column'])
-
conf.env.prepend_value('CFLAGS', '-I' + os.path.abspath('.'))
conf.env.prepend_value('CXXFLAGS', '-I' + os.path.abspath('.'))
g_step = 2
-def set_c99_mode(conf):
- if conf.env.MSVC_COMPILER:
- # MSVC has no hope or desire to compile C99, just compile as C++
- conf.env.append_unique('CFLAGS', ['-TP'])
- else:
- conf.env.append_unique('CFLAGS', ['-std=c99'])
-
def set_local_lib(conf, name, has_objects):
var_name = 'HAVE_' + nameify(name.upper())
define(conf, var_name, 1)
excl='**/_*'))
# Version code file generation
-def build_version_files(header_path, source_path, domain, major, minor, micro):
+def build_version_files(header_path, source_path, domain, major, minor, micro, exportname, visheader):
header_path = os.path.abspath(header_path)
source_path = os.path.abspath(source_path)
text = "int " + domain + "_major_version = " + str(major) + ";\n"
text = "#ifndef __" + domain + "_version_h__\n"
text += "#define __" + domain + "_version_h__\n"
- text += " extern const char* " + domain + "_revision;\n"
- text += " extern int " + domain + "_major_version;\n"
- text += " extern int " + domain + "_minor_version;\n"
- text += " extern int " + domain + "_micro_version;\n"
+ if visheader != '':
+ text += "#include \"" + visheader + "\"\n"
+ text += exportname + " extern const char* " + domain + "_revision;\n"
+ text += exportname + " extern int " + domain + "_major_version;\n"
+ text += exportname + " extern int " + domain + "_minor_version;\n"
+ text += exportname + " extern int " + domain + "_micro_version;\n"
text += "#endif /* __" + domain + "_version_h__ */\n"
try:
o = open(header_path, 'w')
return None
+# Internationalization with gettext
def build_i18n_pot(bld, srcdir, dir, name, sources, copyright_holder=None):
Logs.info('Generating pot file from %s' % name)
pot_file = '%s.pot' % name
# Generate coverage data
subprocess.call(('lcov -c %s -b %s' % (diropts, base)).split(),
stdout=coverage_lcov, stderr=coverage_log)
-
+
# Strip unwanted stuff
subprocess.call(
['lcov', '--remove', 'coverage.lcov'] + remove,
stdout=coverage_stripped_lcov, stderr=coverage_log)
-
+
# Generate HTML coverage output
if not os.path.isdir('coverage'):
os.makedirs('coverage')
subprocess.call('genhtml -o coverage coverage-stripped.lcov'.split(),
stdout=coverage_log, stderr=coverage_log)
-
+
except:
Logs.warn('Failed to run lcov, no coverage report will be generated')
finally:
Logs.pprint('GREEN', '** Pass: All %s.%s tests passed' % (appname, name))
else:
Logs.pprint('RED', '** FAIL: %d %s.%s tests failed' % (failures, appname, name))
-
-def run_ldconfig(ctx):
- if (ctx.cmd == 'install'
- and not ctx.env['RAN_LDCONFIG']
- and ctx.env['LIBDIR']
- and not 'DESTDIR' in os.environ
- and not Options.options.destdir):
- try:
- Logs.info("Waf: Running `/sbin/ldconfig %s'" % ctx.env['LIBDIR'])
- subprocess.call(['/sbin/ldconfig', ctx.env['LIBDIR']])
- ctx.env['RAN_LDCONFIG'] = True
- except:
- pass
-
-def write_news(name, in_files, out_file, top_entries=None, extra_entries=None):
- import rdflib
- import textwrap
- from time import strftime, strptime
-
- doap = rdflib.Namespace('http://usefulinc.com/ns/doap#')
- dcs = rdflib.Namespace('http://ontologi.es/doap-changeset#')
- rdfs = rdflib.Namespace('http://www.w3.org/2000/01/rdf-schema#')
- foaf = rdflib.Namespace('http://xmlns.com/foaf/0.1/')
- rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
- m = rdflib.ConjunctiveGraph()
-
- try:
- for i in in_files:
- m.parse(i, format='n3')
- except:
- Logs.warn('Error parsing data, unable to generate NEWS')
- return
-
- proj = m.value(None, rdf.type, doap.Project)
- for f in m.triples([proj, rdfs.seeAlso, None]):
- if f[2].endswith('.ttl'):
- m.parse(f[2], format='n3')
-
- entries = {}
- for r in m.triples([proj, doap.release, None]):
- release = r[2]
- revision = m.value(release, doap.revision, None)
- date = m.value(release, doap.created, None)
- blamee = m.value(release, dcs.blame, None)
- changeset = m.value(release, dcs.changeset, None)
- dist = m.value(release, doap['file-release'], None)
-
- if revision and date and blamee and changeset:
- entry = '%s (%s) stable;\n' % (name, revision)
-
- for i in m.triples([changeset, dcs.item, None]):
- item = textwrap.wrap(m.value(i[2], rdfs.label, None), width=79)
- entry += '\n * ' + '\n '.join(item)
- if dist and top_entries is not None:
- if not str(dist) in top_entries:
- top_entries[str(dist)] = []
- top_entries[str(dist)] += [
- '%s: %s' % (name, '\n '.join(item))]
-
- if extra_entries:
- for i in extra_entries[str(dist)]:
- entry += '\n * ' + i
-
- entry += '\n\n --'
-
- blamee_name = m.value(blamee, foaf.name, None)
- blamee_mbox = m.value(blamee, foaf.mbox, None)
- if blamee_name and blamee_mbox:
- entry += ' %s <%s>' % (blamee_name,
- blamee_mbox.replace('mailto:', ''))
-
- entry += ' %s\n\n' % (
- strftime('%a, %d %b %Y %H:%M:%S +0000', strptime(date, '%Y-%m-%d')))
-
- entries[revision] = entry
- else:
- Logs.warn('Ignored incomplete %s release description' % name)
-
- if len(entries) > 0:
- news = open(out_file, 'w')
- for e in sorted(entries.keys(), reverse=True):
- news.write(entries[e])
- news.close()