[935f5c]: trunk / wscript Maximize Restore History

Download this file

wscript    1022 lines (897 with data), 40.2 kB

#! /usr/bin/env python
# encoding: utf-8

import sys, os, re, shutil
import Build, Utils, Options, Logs, Configure, Scripting
from Constants import HEXVERSION
from Configure import ConfigurationError
from TaskGen import feature
import wscript_dsp

# Waf version check, for global waf installs

try:
    from Constants import WAFVERSION
except:
    WAFVERSION='1.0.0'
if WAFVERSION[:3] != '1.5':
    print('Incompatible Waf, use 1.5')
    sys.exit (1)

# these variables are mandatory ('/' are converted automatically)
srcdir = '.'
blddir = 'build'
use_2to3 = True

# used by waf dist and waf build
VERSION='0.30.0git'
APPNAME='guitarix'

good_faust_versions = ['0.9.46','0.9.55','0.9.58','0.9.65']

g_maxlen = 40 # maximum width of message for 2-column display


################################################################
# options defined for waf configure
################################################################

def set_options(opt):
    
    def add_enable_option (option, desc, group=None, disable=False):
        if group == None:
            group = opt
        option_ = option.replace ('-', '_')
        group.add_option ('--enable-' + option, action='store_true',
            default=False, help='Enable ' + desc, dest='enable_' + option_)
        group.add_option ('--disable-' + option, action='store_true',
            default=disable, help='Disable ' + desc, dest='disable_' + option_)

    opt.tool_options('gcov')
    opt.tool_options ('intltool')
    group = opt.add_option_group ('Localization and documentation', '')
    add_enable_option ('nls', 'native language support', group)

    opt.tool_options('compiler_cxx')
    comp = opt.get_option_group("--check-cxx-compiler")

    comp.add_option('--debug',
                    action='store_const',
                    default=False,
                    const=True,
                    help='set compiler flags for a debug build')

    comp.add_option('--cxxflags-release',
                    type='string',
                    default='-O3 -DNDEBUG',
                    dest='cxxflags_release',
                    help='additional C++ compiler flags for release version (not used if --debug) [Default: %default]')

    comp.add_option('--cxxflags-debug',
                    type='string',
                    default='-O2 -g -fstack-protector-all',
                    dest='cxxflags_debug',
                    help='additional C++ compiler flags for debug version (only used if --debug) [Default: %default]')

    comp.add_option('--cxxflags',
                    type='string',
                    default='-Wall', # -fomit-frame-pointer -ffast-math -fstrength-reduce -mmmx -mfpmath=sse -DUSE_XMMINTRIN -pipe
                    dest='cxxflags',
                    help='C++ base compiler flags [Default: %default]')

    comp.add_option('--ldflags',
                    type='string',
                    default='', 
                    dest='ldflags',
                    help='C++ base linker flags ')

    comp.add_option('--optimization',
                    action='store_const',
                    default=False, #'-fomit-frame-pointer -ffast-math -fstrength-reduce -pipe',
                    const=True,
                    help='automatically select additional C++ compiler optimization flags for the current platform')

    comp.add_option('--no-desktop-update',
                    action='store_const',
                    default=False, #'-fomit-frame-pointer -ffast-math -fstrength-reduce -pipe',
                    const=True,
                    help='dont automatically update desktop database')


    opt.recurse('libgxw/gxw')
    opt.recurse('libgxwmm/gxwmm')

    comp = opt.add_option_group("Additional Library Options")

    comp.add_option('--includeresampler',
                    action='store_const',
                    default=False,
                    const=True,
                    help='build with included local zita-resample libary (Default NO)')

    comp.add_option('--includeconvolver',
                    action='store_const',
                    default=False,
                    const=True,
                    help='build with included local zita-convolver libary (Default NO)')

    comp.add_option('--convolver-ffmpeg',
                    action='store_const',
                    default=False,
                    const=True,
                    help='modified zita-convolver libary that uses ffmpeg instead of fftw3 for FFT (Default NO)')

    comp.add_option('--libdir',
                   type='string',
                   default='', 
                   dest='libdir',
                   help=('library install path '),
                   )

    faust = opt.add_option_group("Faust-Compiler")

    if len(good_faust_versions) == 1:
        faust_vers_str = good_faust_versions[0]
    else:
        faust_vers_str = "in [%s]" % ", ".join(good_faust_versions)

    faust.add_option('--faust',
                     action='store_const',
                     default=False,
                     const=True,
                     help=('use faust even if the installed version is not %s'
                           % faust_vers_str))

    faust.add_option('--no-faust',
                     action='store_const',
                     default=False,
                     const=True,
                     help="don't use faust, use the pre-built files in faust-generated")

    faust.add_option('--faust-float',
                     action='store_const',
                     default=False,
                     const=True,
                     help="build with faust, single precision")

    faust.add_option('--faust-vectorize',
                     action='store_const',
                     default=False,
                     const=True,
                     help="call faust with --vectorize")

    faust.add_option('--faust-vectorize-float',
                     action='store_const',
                     default=False,
                     const=True,
                     help=("call faust with --vectorize for sources built"
                           "in single (float) precision"))

    faust.add_option('--faust-options', help="additional faust options")

    ladspa = opt.add_option_group("LADSPA Options (installing ladspa modules)")

    ladspa.add_option('--no-ladspa',
                    action='store_const',
                    default=False,
                    const=True,
                    help="don't build ladspa plugins (Default yes)")

    ladspa.add_option('--no-new-ladspa',
                    action='store_const',
                    default=False,
                    const=True,
                    help=("don't build with new ladspa plugins (Default yes)"))


    ladspa.add_option('--ladspadir',
                    type='string',
                    help='LADSPA plugin directory [Default: <prefix>/lib/ladspa]')

    lv2 = opt.add_option_group("LV2 Options (installing LV2 modules)")

    lv2.add_option('--lv2dir',
                    type='string',
                    help='LV2 plugin directory [Default: <prefix>/lib/lv2]')

    lv2.add_option('--no-lv2',
                    action='store_const',
                    default=False,
                    const=True,
                    help=("don't build new lv2 plugins (Default no)"))

    lv2.add_option('--lv2-only',
                    action='store_const',
                    default=False,
                    const=True,
                    help=("build only the lv2 plugins (Default no)"))

    lv2.add_option('--disable-sse',
                    action='store_const',
                    default=False,
                    const=True,
                    help=("disable SSE for lv2 plugins (ARM)"))


    opt.recurse('pygxw')
    opt.recurse('glade-gxw')

    opt.tool_options('compiler_cc') # for pygxw and glade-gxw

    opt.add_option('--dist-tree',
                   type='string',
                   dest='dist_tree',
                   help=("option for 'dist' command: git tree-ish to build"
                         " the archive from [Default: %s]" % 'V%s' % VERSION))

    opt.sub_options('src/gx_head');


################################################################
# waf configure
################################################################

################################################################
# configuration display helper functions
#

def print_msg(msg, nl=True):
    if HEXVERSION > 0x10500:
        s = sys.stderr
    else:
        s = sys.stdout
    if nl:
        t = "\n"
    else:
        t = " "
    s.write(msg+t)

# a bit of waf display formatting
def display_msg(msg, status = None, color = None):
    sr = msg
    global g_maxlen
    g_maxlen = max(g_maxlen, len(msg))
    if status:
        print_msg("%s :" % msg.ljust(g_maxlen),False)
        Utils.pprint(color, status)
    else:
        print_msg("%s" % msg.ljust(g_maxlen))

def error_msg(msg):
    Utils.pprint('RED', msg)

def display_feature(msg, build):
    if build:
        display_msg(msg, "yes", 'CYAN')
    else:
        display_msg(msg, "no", 'YELLOW')

################################################################
# configuration utility functions
#

def option_enabled (option):
    if getattr (Options.options, 'enable_' + option):
        return True
    if getattr (Options.options, 'disable_' + option):
        return False
    return True

def append_optimization_flags(cxxflags):
    cpu_model = None
    x86_flags = None
    try:
        for line in open("/proc/cpuinfo"):
            if cpu_model is None:
                if line.startswith("model name"):
                    cpu_model = line.split(":",1)[1].strip()
            elif x86_flags is None:
                if line.startswith("flags"):
                    x86_flags = line.split(":",1)[1].strip()
            else:
                break
    except IOError:
        pass
    if cpu_model is None or x86_flags is None:
        display_msg("Checking CPU Architecture",
                    "cpu model not found in /proc/cpuinfo",
                    "YELLOW")
        return None
    model = cpu_model.split()
    arch = os.uname()[4]
    if "AMD" in model and "x86_64" in arch:
        cxxflags.append ("-march=k8")
    elif "AMD" in model and "Sempron(tm)" in model:
        cxxflags.append ("-march=native")
    elif "Geode" in model :
        cxxflags.append ("-march=geode")
    elif "Core" in model and "x86_64" in arch:
        cxxflags.append ("-march=core2")
    elif "i386" in arch:
        cxxflags.append ("-march=i386")
    elif "i486" in arch:
        cxxflags.append ("-march=i486")
    elif "i586" in arch:
        cxxflags.append ("-march=i586")
    elif "i686" in arch:
        cxxflags.append ("-march=i686")
    else:
        cxxflags.append ("-march=native")

    if "mmx" in x86_flags:
        cxxflags.append ("-mmmx")
    if "3dnow" in x86_flags:
        cxxflags.append ("-m3dnow")

    if "sse5" in x86_flags:
        cxxflags.append ("-msse5")
        cxxflags.append ("-mfpmath=sse")
    elif "sse4_2" in x86_flags:
        cxxflags.append ("-msse4.2")
        cxxflags.append ("-mfpmath=sse")
    elif "sse4_1" in x86_flags:
        cxxflags.append ("-msse4.1")
        cxxflags.append ("-mfpmath=sse")
    elif "ssse3" in x86_flags:
        cxxflags.append ("-mssse3")
        cxxflags.append ("-mfpmath=sse")
    elif "sse4a" in x86_flags:
        cxxflags.append ("-msse4a")
        cxxflags.append ("-mfpmath=sse")
    elif "sse4" in x86_flags:
        cxxflags.append ("-msse4")
        cxxflags.append ("-mfpmath=sse")
    elif "sse3" in x86_flags:
        cxxflags.append ("-msse3")
        cxxflags.append ("-mfpmath=sse")
    elif "sse2" in x86_flags:
        cxxflags.append ("-msse2")
        cxxflags.append ("-mfpmath=sse")
        #cxxflags.append ("-DUSE_XMMINTRIN")
    elif "sse" in x86_flags:
        cxxflags.append ("-msse")
        cxxflags.append ("-mfpmath=sse")
        # cxxflags.append ("-DUSE_XMMINTRIN")

    if not Options.options.debug:
        cxxflags.append ("-fomit-frame-pointer")
    cxxflags.append ("-ftree-loop-linear")
    cxxflags.append ("-ffinite-math-only")
    cxxflags.append ("-fno-math-errno")
    cxxflags.append ("-fno-signed-zeros")
    #cxxflags.append ("-ffast-math") # quicker but doesn't seem to work (difference in sound output)
    #cxxflags.append ("-malign-double")
    cxxflags.append ("-fstrength-reduce")
    cxxflags.append ("-pipe")
    return cpu_model

@Configure.conf
def cfg_get_variable(self, package, variable, prefix=""):
    p = Utils.pproc.Popen(["pkg-config", "--variable="+variable, package],
                          stdout=Utils.pproc.PIPE, shell=False)
    v = p.communicate()[0].strip()
    if p.returncode or not v:
        self.fatal('fail to get variable %s for package %s' % (variable, package))
    self.env[prefix+variable.upper()] = v


################################################################
# configuration helper functions
#
def sub_file(src_fname, dst_fname, lst):

    f = open(src_fname, 'rU')
    txt = f.read()
    f.close()

    for (key, val) in lst:
        re_pat = re.compile(key, re.M)
        txt = re_pat.sub(val, txt)

    f = open(dst_fname, 'w')
    f.write(txt)
    f.close()

def check_faust(conf):
    if Options.options.no_faust:
        conf.env['FAUST'] = None
        return
    conf.find_program("faust", var='FAUST')
    if not conf.env['FAUST']:
        return
    try:
        s = Utils.cmd_output('%s --version' % conf.env['FAUST'])
    except ValueError:
        Logs.warn('count not execute faust')
        return
    m = re.match(r".*Version\s*(.*)", s)
    if not m:
        Logs.warn('could not determine faust version')
    vers = m.group(1)
    conf.env["FAUST_VERSION"] = vers
    if vers not in good_faust_versions and not Options.options.faust:
        conf.env['FAUST'] = None
        conf.check_message_custom('faust','version',"can't use %s (check ./waf --help)" % vers,color='YELLOW')
    else:
        conf.check_message('faust','version',1,vers)
    conf.env['FAUST_DOUBLE'] = not Options.options.faust_float
    conf.env['FAUST_VECTORIZE'] = Options.options.faust_vectorize
    conf.env['FAUST_VECTORIZE_FLOAT'] = Options.options.faust_vectorize_float
    conf.env['FAUST_OPTIONS'] = Options.options.faust_options

def check_cloop(conf):
    code = """
    int
    main (void)
    {
    #define max(x, y) (((x) > (y)) ? (x) : (y))
    #define min(x, y) (((x) < (y)) ? (x) : (y))
    for (int p1=0;p1<=5;p1++) {
        for (int p2=0;p2<=10;p2++) {
            for (int i=max(2*p1,0);i<=min(10,2*p1+1);i++) {
                for (int j=max(2*p2,0);j<=min(20,2*p2+1);j++) {
                    ;
                }
            }
        }
    }
    return 0;
    }
    """
    msg = "Checking for libcloog-ppl0" 
    conf.check_cxx(msg = msg, fragment=code, cxxflags=[ '-O3', '-ftree-loop-linear'], define_name="NOOPT")

def check_boost(conf):
    code="""
    #include <boost/system/error_code.hpp>
    int main() { boost::system::error_code c; }
    """
    msg = "Checking for boost-system " 
    conf.check_cxx(msg = msg, fragment=code, lib="boost_system", uselib_store="BOOST_SYSTEM", mandatory=1)
    # some boost (>1.49) versions depend on boost-system so we will check for it first
    # and later link against boost_system were boost headers are included.
    boost_atleast_version = 104200
    boost_atleast_vermsg = "1.42"
    code="""
    #include <boost/version.hpp>
    #include <boost/format.hpp>
    #include <boost/thread.hpp>
    #if BOOST_VERSION < %d
    #error
    #endif
    int main(){ return 0; }
    """ % boost_atleast_version
    msg = "Checking for boost >= %s" % boost_atleast_vermsg
    conf.check_cxx(msg = msg, fragment=code, lib="boost_system", mandatory=1)
    # not needed: with boost 1.42 Guitarix doesn't generate code which
    #             references the boost threading lib
    #msg = "Checking for boost_thread%%s >= %s" % boost_atleast_vermsg
    #try:
    #    conf.check_cxx(
    #        msg = msg % "", fragment=code, lib="boost_thread", uselib_store="BOOST_THREAD",
    #        errmsg="not found, trying boost_thread-mt", mandatory=1)
    #except ConfigurationError:
    #    conf.check_cxx(
    #        msg = msg % "-mt",fragment=code, lib="boost_thread-mt",
    #        uselib_store="BOOST_THREAD", mandatory=1)

def check_zita_convolver(opt, conf):
    conf.env['CONVOLVER_FFMPEG'] = False
    if opt.includeconvolver:
        conf.env['ZITA_CONVOLVER'] = False
    elif opt.convolver_ffmpeg:
        conf.env['ZITA_CONVOLVER'] = False
        conf.env['CONVOLVER_FFMPEG'] = True
    else:
        expected_zita_convolver_version = 3
        code="""
        #include <zita-convolver.h>
        #if ZITA_CONVOLVER_MAJOR_VERSION != %d
        #error
        #endif
        int main(){ return 0; }
        """ % expected_zita_convolver_version
        conf.check_cxx(
            fragment=code,
            lib="zita-convolver",
            uselib_store='ZITA_CONVOLVER',
            msg='Checking for zita-convolver >= %d.0' % expected_zita_convolver_version,
            errmsg="version %d not found, using ours" % expected_zita_convolver_version,
            define_name="ZITA_CONVOLVER")

def check_zita_resampler(opt, conf):
    if opt.includeresampler:
        conf.env['ZITA_RESAMPLER'] = False
    else:
        expected_zita_resampler_version = 1
        code="""
        #include <zita-resampler/resampler.h>
        #include <zita-resampler/resampler-table.h>
        #if ZITA_RESAMPLER_MAJOR_VERSION != %d
        #error
        #endif
        int main(){ return 0; }
        """ % expected_zita_resampler_version
        conf.check_cxx(
            fragment=code,
            lib='zita-resampler',
            uselib_store='ZITA_RESAMPLER',
            msg='Checking for zita-resampler >= %d.0' % expected_zita_resampler_version,
            errmsg="version %d not found, using ours" % expected_zita_resampler_version,
            define_name="ZITA_RESAMPLER")

# Taken from Geany's wscript, modified to support LINGUAS variable
def write_linguas_file (self):
    linguas = ''
    # Depending on Waf version, getcwd() is different
    if os.path.exists ('./po'):
        podir = './po'
    else:
        podir = '../po'
    if 'LINGUAS' in Build.bld.env:
        files = Build.bld.env['LINGUAS']
        for f in files.split (' '):
            if os.path.exists (podir + '/' + f + '.po'):
                linguas += f + ' '
    else:
        files = os.listdir (podir)
        for f in files:
            if f.endswith ('.po'):
                linguas += '%s \n' % f[:-3]
    f = open (podir + '/LINGUAS', 'w')
    f.write ('# This file is autogenerated. Do not edit.\n%s' % linguas)
    f.close ()
write_linguas_file = feature ('intltool_po')(write_linguas_file)


################################################################
# guitarix waf configuration
#
 
def configure(conf):
    opt = Options.options
    if opt.disable_sse and opt.optimization:
        display_msg("configuration error", " cant use --disable-sse and --optimization together", 'RED')
        sys.exit(1)

    if 'LINGUAS' in os.environ: conf.env['LINGUAS'] = os.environ['LINGUAS']

    platform = Utils.detect_platform()
    conf.env['IS_MACOSX'] = platform == 'darwin'
    conf.env['IS_LINUX'] = platform == 'linux' or platform == 'posix'
    conf.env['IS_SUN'] = platform == 'sunos'

    if conf.env['IS_LINUX']:
        conf.define ('IS_LINUX', platform )

    if conf.env['IS_MACOSX']:
        conf.define ('IS_MACOSX', platform )

    if conf.env['IS_SUN']:
        conf.define ('IS_SUN', platform )

    conf.env['OS'] = platform

    def option_checkfatal (option, desc):
        if hasattr (opt, 'enable_' + option):
            if getattr (opt, 'enable_' + option):
                Utils.pprint ('RED', desc + ' N/A')
                sys.exit (1)
                
    if option_enabled ('nls'):
        conf.check_tool ('intltool')
        if conf.env['INTLTOOL'] and conf.env['POCOM']:
            nls = 'yes'
        else:
            option_checkfatal ('nls', 'localization')
            nls = 'N/A'
            conf.define ('DISABLE_NLS', 1)
    else:
        nls = 'no '
        conf.define ('DISABLE_NLS', 1)
        #sub_file('guitarix.desktop.in', 'build/default/guitarix.desktop', (('^_', '%s' % ""), ))
        sub_file('guitarix.desktop.in', 'guitarix.desktop._in', (('^_', '%s' % ""), ))
    conf.define ('GETTEXT_PACKAGE', APPNAME)

    conf.define ('ENABLE_NLS', [0,1][nls == 'yes'])
    # compiler
    conf.check_tool('compiler_cxx')
    if opt.with_gcov:
        conf.check_tool('gcov')
    if opt.python_wrapper or opt.glade_support:
        conf.check_tool('compiler_cc')
    conf.env['shlib_LINKFLAGS'].append("-fPIC") # error in waf 1.5.18?
    # linker flags
    conf.env.append_value('LDFLAGS', opt.ldflags.split())
    conf.env['LINKFLAGS'] = conf.env['LDFLAGS']
    if opt.lv2_only:
        opt.no_lv2 = False
        opt.no_ladspa = True
        opt.no_new_ladspa = True
        conf.env['NO_MAIN'] = True
        opt.no_desktop_update = True
    # needed libaries
    try:
        conf.check_cfg(package='jack', atleast_version='0.116.2', max_version='1.8.0', args='--cflags --libs', uselib_store='JACK', mandatory=1)
    except ConfigurationError:
        conf.check_cfg(package='jack', atleast_version='1.9.2', args='--cflags --libs', uselib_store='JACK', mandatory=1)
    # jack_session support
    code = "#include <jack/session.h>\nint main(){return JackSessionID != 0;}"
    conf.check_cxx(fragment=code, msg="Checking for jack session support", define_name='HAVE_JACK_SESSION')

    conf.check_cfg(package='sndfile', atleast_version='1.0.17', args='--cflags --libs', uselib_store='SNDFILE', mandatory=1)
    conf.check_cfg(package='gmodule-export-2.0', args='--cflags --libs', uselib_store='GMODULE_EXPORT', mandatory=1)
    conf.check_cfg(package='gtk+-2.0', atleast_version='2.20', args='--cflags --libs', uselib_store='GTK2', mandatory=1)
    conf.check_cfg(package='gthread-2.0', atleast_version='2.24', args='--cflags --libs', uselib_store='GTHREAD', mandatory=1)
    conf.check_cfg(package='glibmm-2.4', atleast_version='2.24', args='--cflags --libs', uselib_store='GLIBMM', mandatory=1)
    conf.check_cfg(package='gtkmm-2.4', atleast_version='2.20', args='--cflags --libs', uselib_store='GTKMM', mandatory=1)
    conf.check_cfg(package='giomm-2.4', atleast_version='2.24', args='--cflags --libs', uselib_store='GIOMM', mandatory=1)
    conf.check_cfg(package='fftw3f', atleast_version='3.1.2', args='--cflags --libs', uselib_store='FFTW3', mandatory=1)
    if opt.convolver_ffmpeg:
        conf.check_cfg(package='libavcodec', args='--cflags --libs', uselib_store='LIBAVCODEC', mandatory=1)
        conf.check_cfg(package='libavutil', args='--cflags --libs', uselib_store='LIBAVUTIL', mandatory=1)
    conf.check_cfg(package='lrdf', args='--cflags --libs', uselib_store='LRDF', mandatory=1)
    if not opt.no_lv2:
        conf.check_cfg(package='lv2', atleast_version='1.2.0',args='--cflags --libs', uselib_store='LV2CORE', mandatory=1)
    conf.check(header_name='ladspa.h', mandatory=1)
    conf.check_cfg(package='lilv-0', args='--cflags --libs', uselib_store='LILV', mandatory=1)

    check_boost(conf)
    check_zita_convolver(opt, conf)
    check_zita_resampler(opt, conf)
    conf.find_program("gperf", var='HAVE_GPERF')
    check_faust(conf)
    if conf.env['FAUST']:
        if Options.options.faust_vectorize and Options.options.faust_vectorize_float:
            display_msg("configuration error", "conflicting options --faust-vectorize and --faust-vectorize-float", 'RED')
            sys.exit(1)
    else:
        if Options.options.faust_float:
            display_msg("configuration error", " can't use --faust-float without faust", 'RED')
            sys.exit(1)
        if Options.options.faust_vectorize:
            display_msg("configuration error", " can't use --faust-vectorize without faust", 'RED')
            sys.exit(1)
        if Options.options.faust_vectorize_float:
            display_msg("configuration error", " can't use --faust-vectorize-float without faust", 'RED')
            sys.exit(1)
        if Options.options.faust_options:
            display_msg("configuration error", " can't use --faust-options without faust", 'RED')
            sys.exit(1)

    # directory
    conf.env['SHAREDIR'] = conf.env['PREFIX'] + '/share'

    # defines for compilation
    gxsharedir = os.path.normpath(os.path.join(conf.env['SHAREDIR'], 'gx_head'))
    conf.define('GX_STYLE_DIR', os.path.join(gxsharedir,'skins'))
    if not opt.no_lv2:
        conf.define('GX_LV2_STYLE_DIR', os.path.join(conf.env['GX_STYLE_DIR'],'LV2'))
    conf.define('GX_FACTORY_DIR', os.path.join(gxsharedir,'factorysettings'))
    conf.define('GX_SOUND_DIR', os.path.join(gxsharedir,'sounds'))
    conf.define('GX_SOUND_BPB_DIR', os.path.join(conf.env['GX_SOUND_DIR'],'bands'))
    conf.define('GX_SOUND_BPA_DIR', os.path.join(conf.env['GX_SOUND_DIR'],'amps'))
    conf.define('GX_BUILDER_DIR', os.path.join(gxsharedir,'builder'))
    conf.define('GX_ICON_DIR', os.path.normpath(os.path.join(conf.env['SHAREDIR'], 'guitarix','icons')))
    conf.define('GX_PIXMAPS_DIR', os.path.normpath(os.path.join(conf.env['SHAREDIR'], 'pixmaps')))
    conf.define('GX_VERSION', VERSION)
    
    if conf.env.DEST_CPU=='x86_64': 
        conf.define('OS_64_BIT', 1)
    else:
        conf.define('OS_32_BIT', 1)

    if not opt.libdir:
        conf.env['LIBDIR'] = os.path.normpath(os.path.join(conf.env['PREFIX'], 'lib'))
    else:
        conf.env['LIBDIR'] = opt.libdir

    conf.env['BINDIR'] = os.path.normpath(os.path.join(conf.env['PREFIX'], 'bin'))
    conf.env['DESKAPPS_DIR'] = os.path.normpath(os.path.join(conf.env['SHAREDIR'], 'applications'))
    conf.env['BIN_NAME'] = APPNAME

    conf.env['LV2'] =  not opt.no_lv2
    conf.env['NOSSE'] =  opt.disable_sse
    if not opt.no_lv2:
        if opt.lv2dir:
            conf.env['LV2DIR'] = opt.lv2dir
        else:
            conf.env['LV2DIR'] = os.path.normpath(os.path.join(conf.env['LIBDIR'], 'lv2'))

    conf.env['NEW_LADSPA'] = not opt.no_ladspa and not opt.no_new_ladspa
    conf.env['LADSPA'] = not opt.no_ladspa
    if not opt.no_ladspa:
        if opt.ladspadir:
            conf.env['LADSPADIR'] = opt.ladspadir
        else:
            conf.env['LADSPADIR'] = os.path.normpath(os.path.join(
                conf.env['LIBDIR'], 'ladspa'))

    # g++ flags
    cxxflags = opt.cxxflags.split()
    if opt.debug:
        cxxflags += opt.cxxflags_debug.split()
    else:
        cxxflags += opt.cxxflags_release.split()
    cpu_model = None
    if opt.optimization:
        check_cloop(conf)
        if conf.env['NOOPT']:
            conf.env['OPT'] = False
            cpu_model = append_optimization_flags(cxxflags)
    conf.env['CXXFLAGS'] += cxxflags

    if opt.no_desktop_update:
        conf.env["NO_UPDATE_DESKTOP_DATA_BASE"] = True

    # pygobject is used by both python and c++ wrapper
    if opt.python_wrapper or opt.generate_cpp_wrapper:
        conf.check_tool('python')
        conf.check_cfg(package='pygobject-2.0', args='--cflags --libs', uselib_store='PYGOBJECT', mandatory=True)
        conf.cfg_get_variable(package='pygobject-2.0', variable='codegendir')

    if not conf.env['NO_MAIN']:
        conf.sub_config('src/gx_head');
    if conf.env['FAUST']:
        conf.sub_config('src/faust');
    conf.sub_config('src/plugins');
    if conf.env["LADSPA"]:   
        conf.sub_config('ladspa');
    if conf.env["LV2"]:
        opt.shared_lib = True;
        conf.sub_config('src/LV2');
        
        # config subdirs
    conf.sub_config('pygxw');
    conf.sub_config('glade-gxw');
    conf.sub_config('libgxwmm');
    conf.sub_config('libgxw/gxw');

    conf.sub_config('rcstyles');
    if conf.env["GX_LIB_DEV"]:
        pa = conf.env['PREFIX']
        sub_file('./libgxw/gxw.pc.in', './libgxw/gxw.pc', (('prefix=/path', 'prefix=%s' % pa), ))
        sub_file('./libgxw/gxw.pc', './libgxw/gxw.pc', (('libdir=/path','libdir=%s' % conf.env['LIBDIR']), ))
        sub_file('./libgxwmm/gxwmm.pc.in', './libgxwmm/gxwmm.pc', (('prefix=/path', 'prefix=%s' % pa), ))
        sub_file('./libgxwmm/gxwmm.pc', './libgxwmm/gxwmm.pc', (('libdir=/path','libdir=%s' % conf.env['LIBDIR']), ))

    # writing config.h
    conf.write_config_header('config.h')

    # some output
    print("")
    display_msg("==================")
    version_msg = "GUITARIX II " + VERSION
    print_msg(version_msg)
    
    print_msg("")
    display_msg("OS ", conf.env['OS'], 'CYAN')
    if conf.env['NO_MAIN']:
        display_msg("Guitarix main build ", "dissabled", 'RED')
    if cpu_model:
        display_msg("CPU version" , "%s" % cpu_model, "CYAN")
    if not conf.env['NOOPT'] and opt.optimization:
        display_msg("package libcloog-ppl0 not found", "optimization is disabled", "RED")
    display_msg("C++ flags", " ".join(conf.env['CXXFLAGS']), 'CYAN')
    display_msg("Link flags", " ".join(conf.env['LINKFLAGS']), 'CYAN')
    display_msg("Compiler %s version" %conf.env["CXX"], "%s" % ".".join(conf.env["CC_VERSION"]), "CYAN")
    display_feature("Use prebuild faust files", not conf.env['FAUST'])
    if not opt.faust_float:
        display_msg("Use faust precision", "double", 'CYAN')
    else:
        display_msg("Use faust precision", "single", 'CYAN')
    if opt.faust_vectorize:
        display_msg("call faust with --vectorize", conf.env['FAUST_VECTORIZE'], 'CYAN')
    if opt.faust_vectorize_float:
        display_msg("faust vectorize float prec.", conf.env['FAUST_VECTORIZE_FLOAT'], 'CYAN')
    if opt.faust_options:
        display_msg("Additional faust options", conf.env['FAUST_OPTIONS'], 'CYAN')
    display_feature("Use prebuild gperf files", not conf.env["HAVE_GPERF"])
    display_feature("Avahi service discovery", conf.env["HAVE_AVAHI"])
    display_feature("Bluetooth rfcomm", conf.env["HAVE_BLUEZ"])
    display_feature("Use internal zita-resampler", not conf.env['ZITA_RESAMPLER'])
    if conf.env['CONVOLVER_FFMPEG']:
        display_feature("Use zita-convolver-ffmpeg", True)
    else:
        display_feature("Use internal zita-convolver", not conf.env['ZITA_CONVOLVER'])
    display_feature("Jack Session Support", conf.env['HAVE_JACK_SESSION'])

    display_feature("build ladspa plugins", conf.env['LADSPA'])
    display_feature("build lv2 plugins", conf.env['LV2'])
    if not opt.no_lv2:
        display_feature("SSE2 support found", conf.env['SSE2'])
        display_feature("SSE2 support disabled", conf.env['NOSSE'])
    display_feature("skip Python Library Wrapper", not conf.env['GX_PYTHON_WRAPPER'])
    display_feature("use prebuild C++ Library Wrapper", conf.env['USE_GENERATED_CPP'])
    display_feature("skip building shared lib", not conf.env['GX_LIB_SHARED'])
    display_feature("skip install lib-dev", not conf.env['GX_LIB_DEV'])
    display_feature("run ldconfig tool", not conf.env['NO_LDCONFIG'])
    display_feature("update desktop database", not conf.env['NO_UPDATE_DESKTOP_DATA_BASE'])
    display_feature("Localization  (intltool)", conf.env['ENABLE_NLS'])
    display_feature("skip glade support", not conf.env['GX_GLADE_SUPPORT'])
    if conf.env['GX_GLADE_SUPPORT']:
        display_msg("glade catalog dir", conf.env['GLADE_CATALOG_DIR'], 'CYAN')
        display_msg("glade modules dir", conf.env['GLADE_MODULES_DIR'], 'CYAN')
    display_msg("Install prefix", conf.env['PREFIX'], 'CYAN')
    if not conf.env['NO_MAIN']:
        display_msg("Install binary", conf.env['BINDIR'], 'CYAN')
    display_msg("Install library", conf.env['LIBDIR'], 'CYAN')

    if not opt.no_ladspa:
        display_msg("Install ladspa", conf.env['LADSPADIR'], 'CYAN')
    if not opt.no_lv2:
        display_msg("Install lv2", conf.env['LV2DIR'], 'CYAN')
    if not conf.env['NO_MAIN']:
        display_msg("Guitarix shared files directory", gxsharedir, 'CYAN')
        display_msg("Guitarix pixmaps directory", conf.env['GX_PIXMAPS_DIR'], 'CYAN')
    if conf.env['g++']:
       error_msg("ERROR       !!! Compiler version is too old !!!")

    print_msg("")


################################################################
# Build / Install
################################################################

def post(ctx):
    if os.geteuid() == 0:
        Utils.exec_command('/sbin/ldconfig')

def build(bld):
    if bld.env['INTLTOOL']:
        obj = bld.new_task_gen ('intltool_po')
        obj.podir = 'po'
        obj.appname = APPNAME

    # process subfolders from here
    if bld.env["LADSPA"]:
        bld.add_subdirs('ladspa')
    bld.add_subdirs('libgxw/gxw')
    bld.add_group()
    bld.add_subdirs('libgxwmm')
    bld.add_subdirs('glade-gxw')
    bld.add_subdirs('pygxw')
    if not bld.env['NO_MAIN']:
        bld.add_subdirs('src/faust')
        bld.add_subdirs('src/plugins')
        bld.add_subdirs('rcstyles')
        bld.add_subdirs('pixmaps')
        bld.add_subdirs('src/gx_head')
    if bld.env["NEW_LADSPA"]:
        bld.add_subdirs('src/ladspa')
    if bld.env["LV2"]:
        bld.add_subdirs('src/LV2')

    if not bld.env['NO_MAIN']:
        bld.install_files(bld.env['DESKAPPS_DIR'], 'guitarix.desktop', chmod=0o644)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/dirlist.js', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/funkmuscle.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/dlp_ae.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/zettberlin.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/autoandimat.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/jp_n_o_s.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/kokoko3k.gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/univibe', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/univibe_mono', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/flanger_mono_gx', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/jconv', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/mbc', chmod=0o664)
        bld.install_files(bld.env['GX_FACTORY_DIR'], 'factorysettings/mbcs', chmod=0o664)
        # "greathall.wav" is referenced in the source (keep in sync when changing)
        bld.install_files(bld.env['GX_SOUND_DIR'], './IR/greathall.wav', chmod=0o664)
        bld.install_files(bld.env['GX_SOUND_BPB_DIR'], './IR/BestPlugins_Bands/*', chmod=0o664)
        bld.install_files(bld.env['GX_SOUND_BPA_DIR'], './IR/BestPlugins_Amps/*', chmod=0o664)

        if not bld.env['DISABLE_NLS']:
            gen_desktop = bld(features  = "intltool_in",
                podir     = "po",
                flags     = ["-d", "-q", "-u", "-c"],
                source    = 'guitarix.desktop.in',
                target    = 'guitarix.desktop',
                install_path = "${DATADIR}/applications",
            )
        
            # hacked in scanner method so the desktop file gets rebuild
            # when any po file changes; don't know if there is a better way
            gen_desktop_create_task = gen_desktop.create_task
            def gen_desktop_add_scanner(*args,**kw):
                task = gen_desktop_create_task(*args,**kw)
                def po_scanner():
                    gen = task.generator
                    podir = gen.bld.srcnode.find_dir(gen.podir)
                    return (podir.ant_glob("*.po", flat=False), [])
                task.scan = po_scanner
                return task
            gen_desktop.create_task = gen_desktop_add_scanner
        else:
            gen_desktop = bld(features  = "subst",
                source    = 'guitarix.desktop._in',
                target    = 'guitarix.desktop',
                install_path = "${DATADIR}/applications",
                VAR        = ""
            )
            gen_desktop.create_task
        if Options.commands["install"]:  ## newer waf version: bld.cmd == 'install'
            if not bld.env["NO_UPDATE_DESKTOP_DATA_BASE"]:
                try:
                    bld.exec_command(["update-desktop-database", Utils.subst_vars("${DATADIR}/applications", bld.env)])
                except:
                    pass

    if bld.env["GX_LIB_SHARED"]:
        if not bld.env["NO_LDCONFIG"]:
            bld.add_post_fun(post)
    if bld.env["GX_LIB_DEV"]:
        bld.install_files('${PREFIX}/include/gxw','libgxw/gxw/*.h')
        bld.install_files('${PREFIX}/include','libgxw/gxw.h')
        bld.install_files('${LIBDIR}/pkgconfig', './libgxw/gxw.pc')
        bld.install_files('${PREFIX}/include/gxwmm','libgxwmm/gxwmm-generated/*.h')
        bld.install_files('${PREFIX}/include/gxwmm','libgxwmm/gxwmm/*.h')
        bld.install_files('${PREFIX}/include','libgxwmm/gxwmm.h')
        bld.install_files('${LIBDIR}/pkgconfig', './libgxwmm/gxwmm.pc')

################################################################
# other commands
################################################################

def etags(ctx):
    "Create an Emacs ETAGS file for the src directory"
    cmd = ("etags -o TAGS libgxw/gxw/*.cpp libgxwmm/gxwmm/*.ccg libgxwmm/gxwmm/*.hg"
           " libgxw/gxw/*.h src/gx_head/engine/*.cpp src/gx_head/engine/*.cc"
           " src/gx_head/gui/*.cpp src/headers/*.h")
    Logs.debug("runner: system command -> %s" % cmd)
    Utils.exec_command(cmd)

def update_pot(ctx):
    "extract all text for localization into po/untitled.pot"
    Utils.exec_command("cd po && intltool-update -p")

dir_prefix = "guitarix"
tar_prefix = "guitarix2"
tar_ext = ".tar.bz2"

def _make_dict():
    import Options
    t = Options.options.dist_tree
    if not t:
        t = 'V%s' % VERSION
    d = dict(t=t, d=dir_prefix, p=tar_prefix, e=tar_ext)
    if re.match(r"V\d", t):
        d["v"] = t[1:]
        if Utils.exec_command("git show-ref --verify --quiet --tags refs/tags/'%(t)s'" % d) != 0:
            raise Utils.WafError(
                "tag '%(t)s' not found: please create revision tag" % d)
    else:
        d["v"] = t[1:]
        try:
            s = Utils.cmd_output("git show-ref --hash=8 '%(t)s' | sort -u" % d)
            if not s:
                raise ValueError
            s = s.split()
            if len(s) > 1:
                raise Utils.WafError(
                    "git tree-ish '%(t)s' is ambiguous" % d)
            s = s[0]
        except ValueError:
            raise Utils.WafError(
                "git tree-ish '%(t)s' not found" % d)
        d["v"] = "git-" + s.strip()
    return d

def dist(ctx):
    "makes a tarball for redistributing the sources"
    Utils.exec_command(
        "git archive --prefix=%(d)s-%(v)s/ %(t)s ."
        " | bzip2 > %(p)s-%(v)s%(e)s" % _make_dict())

def distcheck(ctx):
    '''checks if the sources compile (tarball from 'dist')'''
    import tempfile, tarfile
    waf = os.path.abspath(sys.argv[0])
    d = _make_dict()
    tarball = "%(p)s-%(v)s%(e)s" % d
    path = "%(d)s-%(v)s" % d
    if os.path.exists(path):
        try:
            raw_input("%s exists, press enter to remove (stop with Ctrl-C)\n" % path)
        except KeyboardInterrupt:
            print("")
            raise Utils.WafError('distcheck cancelled')
            return
        else:
            print("removing %s" % path)
        shutil.rmtree(path)
    print("creating tarball and extracting files into %s" % path)
    dist(ctx)
    t = tarfile.open(tarball)
    for x in t:
        t.extract(x)
    t.close()
    build_path = path
    instdir = tempfile.mkdtemp('.inst', path)
    cmdargs = [waf,'configure','build','install','uninstall', '--destdir='+instdir]
    print('starting "%s"' % (" ".join(cmdargs)))
    print("")
    ret = Utils.pproc.Popen(cmdargs, cwd=build_path).wait()
    if ret:
        raise Utils.WafError('distcheck failed with code %i'%ret)
    if os.path.exists(instdir):
        raise Utils.WafError('distcheck succeeded, but files were left in %s'%instdir)
    shutil.rmtree(path)