1import inspect, pprint, os
2from waflib import Configure
3from waflib.Errors import WafError
4from waflib.TaskGen import feature, before_method
5
6@feature('lv2')
7@before_method('apply_link')
8def lv2_prepare_link(self):
9    self.env.cxxshlib_PATTERN = '%s.so'
10
11def get_lv2_base(bld, kw, nframes=3):
12    try:
13        lv2_base = kw['lv2_base']
14    except KeyError:
15        pass
16    else:
17        return lv2_base, '${LV2DIR}/%s.lv2' % lv2_base
18    cf = inspect.currentframe()
19    for i in range(nframes):
20        cf = cf.f_back
21    fi = inspect.getframeinfo(cf)
22    fn = bld.root.make_node(fi.filename).srcpath()
23    raise WafError(
24        '{}[{}]: lv2_base not set in lv2 task generator:\n{}'.format(
25            fn, fi.lineno, pprint.pformat(kw)))
26
27def lv2_add_common(tg, target, install_path, defines=None, linkflags=None, cxxflags=None):
28    tg.features.append('lv2')
29    if not tg.target:
30        tg.target = target
31    if not hasattr(tg, 'install_path'):
32        tg.install_path = install_path
33    if defines:
34        tg.defines = tg.to_list(getattr(tg, 'defines', [])) + tg.to_list(defines)
35    if linkflags:
36        tg.linkflags = tg.to_list(getattr(tg, 'linkflags', [])) + tg.to_list(linkflags)
37    if cxxflags:
38        tg.cxxflags = tg.to_list(getattr(tg, 'cxxflags', [])) + tg.to_list(cxxflags)
39
40@Configure.conf
41def lv2(bld, *k, **kw):
42    lv2_base, dst = get_lv2_base(bld, kw)
43    tg = bld.shlib(features='strip', *k, **kw)
44    cxxflags = []
45    if not bld.env['OPT'] and bld.env['SSE2']:
46        cxxflags = [ "-msse2", "-mfpmath=sse"]
47    lv2_add_common(tg, lv2_base, dst, ["LV2_SO"], cxxflags=cxxflags + ['-fvisibility=hidden','-Wl,-z,relro,-z,now','-Wl,--exclude-libs,ALL'])
48    if bld.env['MODGUI']:
49        bld.install_files(dst, bld.path.ant_glob('*.ttl'), relative_trick=True)
50        bld.install_files(dst, bld.path.ant_glob('modgui/**/*'), relative_trick=True)
51    else:
52        bld.install_files(dst, bld.path.ant_glob('*.ttl', excl=['modgui.ttl']), relative_trick=True)
53    return tg
54
55@Configure.conf
56def lv2_gui(bld, *k, **kw):
57    if not bld.env['LV2GUI']:
58        return None
59    lv2_base, dst = get_lv2_base(bld, kw)
60    tg = bld.shlib(features='strip', *k, **kw)
61    lv2_add_common(tg, lv2_base+'_gui', dst, ["LV2_GUI"], ['-fvisibility=hidden','-Wl,-z,relro,-z,now','-Wl,--exclude-libs,ALL'])
62    return tg
63
64def options(opt):
65    lv2 = opt.add_option_group("LV2 Options (installing LV2 modules)")
66
67    lv2.add_option('--no-lv2',
68                    dest='lv2',
69                    action='store_false',
70                    default=True,
71                    help=("Don't build LV2 plugins (Default no)"))
72
73    lv2.add_option('--no-lv2-gui',
74                    dest='lv2_gui',
75                    action='store_false',
76                    default=True,
77                    help=("Don't build LV2 plugin GUI's (Default no)"))
78
79    lv2.add_option('--mod-lv2',
80                    dest='mod_lv2',
81                    action='store_true',
82                    default=False,
83                    help=("Install MOD LV2 GUI's (Default no)"))
84
85    lv2.add_option('--lv2dir',
86                    type='string',
87                    help='LV2 plugin directory [Default: <prefix>/lib/lv2]')
88
89    lv2.add_option('--disable-sse',
90                    action='store_const',
91                    default=False,
92                    const=True,
93                    help=("disable SSE for lv2 plugins (ARM)"))
94
95def configure(conf):
96    opt = conf.options
97    if not opt.lv2:
98        return
99    env = conf.env
100    env.LV2 = True
101    env.LV2GUI = opt.lv2_gui
102    env.MODGUI = opt.mod_lv2
103    env.NOSSE =  opt.disable_sse
104    conf.check_cfg(package='sigc++-2.0', args='--cflags --libs', uselib_store='SIGC', mandatory=1)
105    conf.check_cfg(package='lv2', args=['--cflags','--libs','lv2 >= 1.2.0'], uselib_store='LV2CORE', mandatory=1)
106    conf.define_with_env('GX_LV2_STYLE_DIR', os.path.join(env.GX_STYLE_DIR,'LV2'))
107    if opt.lv2dir:
108        env.LV2DIR = opt.lv2dir
109    else:
110        env.LV2DIR = os.path.normpath(os.path.join(env.LIBDIR, 'lv2'))
111