GUI toolkit for LV2 plugins
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

347 lines
13 KiB

#!/usr/bin/env python
import os
import sys
from waflib import Logs, Options, TaskGen
from waflib.extras import autowaf
# Library and package version (UNIX style major, minor, micro)
# major increment <=> incompatible changes
# minor increment <=> compatible changes (additions)
# micro increment <=> no interface changes
PUGL_VERSION = '0.2.0'
PUGL_MAJOR_VERSION = '0'
# Mandatory waf variables
APPNAME = 'pugl' # Package name for waf dist
VERSION = PUGL_VERSION # Package version for waf dist
top = '.' # Source directory
out = 'build' # Build directory
def options(ctx):
ctx.load('compiler_c')
opts = ctx.configuration_options()
opts.add_option('--target', default=None, dest='target',
help='target platform (e.g. "win32" or "darwin")')
ctx.add_flags(
opts,
{'all-headers': 'install complete header implementation',
'no-gl': 'do not build OpenGL support',
'no-cairo': 'do not build Cairo support',
'no-static': 'do not build static library',
'no-shared': 'do not build shared library',
'log': 'print GL information to console',
'grab-focus': 'work around keyboard issues by grabbing focus'})
def configure(conf):
conf.load('compiler_c', cache=True)
conf.load('autowaf', cache=True)
autowaf.set_c_lang(conf, 'c99')
conf.env.ALL_HEADERS = Options.options.all_headers
conf.env.TARGET_PLATFORM = Options.options.target or sys.platform
platform = conf.env.TARGET_PLATFORM
if platform == 'darwin':
conf.env.append_unique('CFLAGS', ['-Wno-deprecated-declarations'])
if conf.env.MSVC_COMPILER:
conf.env.append_unique('CFLAGS', ['/wd4191'])
else:
conf.env.append_value('LINKFLAGS', ['-fvisibility=hidden'])
conf.env.append_value('CFLAGS', ['-fvisibility=hidden'])
if Options.options.strict:
conf.env.append_value('CFLAGS', ['-Wunused-parameter',
'-Wno-pedantic'])
conf.check_cc(lib='m', uselib_store='M', mandatory=False)
conf.check_cc(lib='dl', uselib_store='DL', mandatory=False)
# Check for "native" platform dependencies
conf.env.HAVE_GL = False
if platform == 'darwin':
conf.check_cc(framework_name='Cocoa', framework='Cocoa',
uselib_store='COCOA')
if not Options.options.no_gl:
conf.check_cc(framework_name='OpenGL', uselib_store='GL',
mandatory=False)
conf.env.HAVE_GL = conf.env.FRAMEWORK_GL
elif platform == 'win32':
conf.check_cc(lib='gdi32', uselib_store='GDI32')
conf.check_cc(lib='user32', uselib_store='USER32')
if not Options.options.no_gl:
conf.check_cc(lib='opengl32', uselib_store='GL', mandatory=False)
conf.env.HAVE_GL = conf.env.LIB_GL
else:
conf.check_cc(lib='X11', uselib_store='X11')
if not Options.options.no_gl:
glx_fragment = """#include <GL/glx.h>
int main(void) { glXSwapBuffers(0, 0); return 0; }"""
conf.check_cc(lib='GLX', uselib_store='GLX', mandatory=False)
conf.check_cc(lib='GL', uselib_store='GL', mandatory=False)
conf.check_cc(fragment=glx_fragment,
lib='GLX' if conf.env.LIB_GLX else 'GL',
mandatory=False,
msg='Checking for GLX')
conf.env.HAVE_GL = conf.env.LIB_GL or conf.env.LIB_GLX
# Check for Cairo via pkg-config
if not Options.options.no_cairo:
autowaf.check_pkg(conf, 'cairo',
uselib_store = 'CAIRO',
atleast_version = '1.0.0',
mandatory = False)
if Options.options.log:
conf.define('PUGL_VERBOSE', 1)
conf.env.update({
'BUILD_SHARED': not Options.options.no_shared,
'BUILD_STATIC': conf.env.BUILD_TESTS or not Options.options.no_static})
autowaf.set_lib_env(conf, 'pugl', PUGL_VERSION)
conf.write_config_header('pugl_config.h', remove=False)
autowaf.display_summary(
conf,
{"Build static library": bool(conf.env.BUILD_STATIC),
"Build shared library": bool(conf.env.BUILD_SHARED),
"OpenGL support": bool(conf.env.HAVE_GL),
"Cairo support": bool(conf.env.HAVE_CAIRO),
"Verbose console output": conf.is_defined('PUGL_VERBOSE')})
def _build_pc_file(bld, name, desc, target, libname, deps={}, requires=[]):
"Builds a pkg-config file for a library"
env = bld.env
prefix = env.PREFIX
xprefix = os.path.dirname(env.LIBDIR)
uselib = deps.get('uselib', [])
pkg_deps = [l for l in uselib if 'PKG_' + l.lower() in env]
lib_deps = [l for l in uselib if 'PKG_' + l.lower() not in env]
link_flags = [env.LIB_ST % l for l in (deps.get('lib', []) + [libname])]
for l in lib_deps:
link_flags += [env.LIB_ST % l for l in env['LIB_' + l]]
for f in deps.get('framework', []):
link_flags += ['-framework', f]
bld(features='subst',
source='pugl.pc.in',
target='%s-%s.pc' % (target, PUGL_MAJOR_VERSION),
install_path=os.path.join(env.LIBDIR, 'pkgconfig'),
PREFIX=prefix,
EXEC_PREFIX='${prefix}' if xprefix == prefix else xprefix,
LIBDIR='${exec_prefix}/' + os.path.basename(env.LIBDIR),
INCLUDEDIR=env.INCLUDEDIR.replace(prefix, '${prefix}', 1),
NAME=name,
DESCRIPTION=desc,
PUGL_MAJOR_VERSION=PUGL_MAJOR_VERSION,
REQUIRES=' '.join(requires + [p.lower() for p in pkg_deps]),
LIBS=' '.join(link_flags))
def build(bld):
# C Headers
includedir = '${INCLUDEDIR}/pugl-%s/pugl' % PUGL_MAJOR_VERSION
bld.install_files(includedir, bld.path.ant_glob('pugl/*.h'))
bld.install_files(includedir, bld.path.ant_glob('pugl/*.hpp'))
if bld.env.ALL_HEADERS:
detaildir = os.path.join(includedir, 'detail')
bld.install_files(detaildir, bld.path.ant_glob('pugl/detail/*.h'))
bld.install_files(detaildir, bld.path.ant_glob('pugl/detail/*.c'))
# Library dependencies of pugl libraries (for buiding tests)
deps = {}
def build_pugl_lib(name, **kwargs):
deps[name] = {}
for k in ('lib', 'framework', 'uselib'):
deps[name][k] = kwargs.get(k, [])
args = kwargs.copy()
args.update({'includes': ['.'],
'export_includes': ['.'],
'install_path': '${LIBDIR}',
'vnum': PUGL_VERSION})
if bld.env.BUILD_SHARED:
bld(features = 'c cshlib',
name = name,
target = 'pugl_' + name,
cflags = ['-DPUGL_INTERNAL', '-DPUGL_SHARED'],
**args)
if bld.env.BUILD_STATIC:
bld(features = 'c cstlib',
name = 'pugl_%s_static' % name,
target = 'pugl_' + name,
cflags = ['-DPUGL_INTERNAL'],
**args)
def build_platform(platform, **kwargs):
build_pugl_lib(platform, **kwargs)
_build_pc_file(bld, 'Pugl', 'Pugl GUI library core',
'pugl', 'pugl_%s' % platform,
deps=kwargs)
def build_backend(platform, backend, **kwargs):
name = '%s_%s' % (platform, backend)
label = 'OpenGL' if backend == 'gl' else backend.title()
build_pugl_lib(name, **kwargs)
_build_pc_file(bld, 'Pugl %s' % label,
'Pugl GUI library with %s backend' % label,
'pugl-%s' % backend, 'pugl_' + name,
deps=kwargs,
requires=['pugl-%s' % PUGL_MAJOR_VERSION])
lib_source = ['pugl/detail/implementation.c']
if bld.env.TARGET_PLATFORM == 'win32':
platform = 'win'
build_platform('win',
uselib=['GDI32', 'USER32'],
source=lib_source + ['pugl/detail/win.c'])
if bld.env.HAVE_GL:
build_backend('win', 'gl',
uselib=['GDI32', 'USER32', 'GL'],
source=['pugl/detail/win_gl.c'])
if bld.env.HAVE_CAIRO:
build_backend('win', 'cairo',
uselib=['CAIRO', 'GDI32', 'USER32'],
source=['pugl/detail/win_cairo.c'])
elif bld.env.TARGET_PLATFORM == 'darwin':
platform = 'mac'
build_platform('mac',
framework=['Cocoa'],
source=lib_source + ['pugl/detail/mac.m'])
if bld.env.HAVE_GL:
build_backend('mac', 'gl',
framework=['Cocoa', 'OpenGL'],
source=['pugl/detail/mac_gl.m'])
if bld.env.HAVE_CAIRO:
build_backend('mac', 'cairo',
framework=['Cocoa'],
uselib=['CAIRO'],
source=['pugl/detail/mac_cairo.m'])
else:
platform = 'x11'
build_platform('x11',
uselib=['M', 'X11'],
source=lib_source + ['pugl/detail/x11.c'])
if bld.env.HAVE_GL:
glx_lib = 'GLX' if bld.env.LIB_GLX else 'GL'
build_backend('x11', 'gl',
uselib=[glx_lib, 'X11'],
source=['pugl/detail/x11_gl.c'])
if bld.env.HAVE_CAIRO:
build_backend('x11', 'cairo',
uselib=['CAIRO', 'X11'],
source=['pugl/detail/x11_cairo.c'])
def build_test(prog, source, platform, backend, **kwargs):
use = ['pugl_%s_static' % platform,
'pugl_%s_%s_static' % (platform, backend)]
target = prog
if bld.env.TARGET_PLATFORM == 'darwin':
target = '{0}.app/Contents/MacOS/{0}'.format(prog)
bld(features = 'subst',
source = 'resources/Info.plist.in',
target = '{}.app/Contents/Info.plist'.format(prog),
install_path = '',
NAME = prog)
backend_lib = platform + '_' + backend
for k in ('lib', 'framework', 'uselib'):
kwargs.update({k: (kwargs.get(k, []) +
deps.get(platform, {}).get(k, []) +
deps.get(backend_lib, {}).get(k, []))})
bld(features = 'c cprogram',
source = source,
target = target,
use = use,
install_path = '',
**kwargs)
if bld.env.BUILD_TESTS:
for s in ('rect.vert', 'rect.frag'):
# Copy shaders to build directory for test programs
bld(features = 'subst',
is_copy = True,
source = 'shaders/%s' % s,
target = 'shaders/%s' % s)
if bld.env.HAVE_GL:
build_test('pugl_test', ['test/pugl_test.c'],
platform, 'gl', uselib=['GL', 'M'])
build_test('pugl_print_events', ['test/pugl_print_events.c'],
platform, 'stub')
build_test('pugl_gl3_test',
['test/pugl_gl3_test.c', 'test/glad/glad.c'],
platform, 'gl', uselib=['DL', 'GL', 'M'])
if bld.env.HAVE_CAIRO:
build_test('pugl_cairo_test', ['test/pugl_cairo_test.c'],
platform, 'cairo',
uselib=['M', 'CAIRO'])
if bld.env.DOCS:
bld(features = 'subst',
source = 'doc/reference.doxygen.in',
target = 'doc/reference.doxygen',
install_path = '',
PUGL_VERSION = PUGL_VERSION,
PUGL_SRCDIR = os.path.abspath(bld.path.srcpath()))
bld(features = 'doxygen',
doxyfile = 'doc/reference.doxygen')
def test(tst):
pass
def lint(ctx):
"checks code for style issues"
import json
import subprocess
subprocess.call("flake8 wscript --ignore E221,W504,E251,E241",
shell=True)
with open('build/compile_commands.json', 'r') as db:
commands = json.load(db)
files = [c['file'] for c in commands
if os.path.basename(c['file']) != 'glad.c']
subprocess.call(['clang-tidy'] + files, cwd='build')
try:
subprocess.call(['iwyu_tool.py', '-o', 'clang', '-p', 'build'])
except Exception:
Logs.warn('Failed to call iwyu_tool.py')
# Alias .m files to be compiled like .c files, gcc will do the right thing.
@TaskGen.extension('.m')
def m_hook(self, node):
return self.create_compiled_task('c', node)