| import os, platform |
| from waflib import Context |
| |
| out = 'build' |
| top = '.' |
| |
| VERSION = '2020.04' |
| APPNAME = 'glmark2' |
| |
| FLAVORS = { |
| 'dispmanx-glesv2' : 'glmark2-es2-dispmanx', |
| 'drm-gl' : 'glmark2-drm', |
| 'drm-glesv2' : 'glmark2-es2-drm', |
| 'mir-gl' : 'glmark2-mir', |
| 'mir-glesv2' : 'glmark2-es2-mir', |
| 'wayland-gl' : 'glmark2-wayland', |
| 'wayland-glesv2' : 'glmark2-es2-wayland', |
| 'win32-gl': 'glmark2-win32', |
| 'win32-glesv2': 'glmark2-es2', |
| 'x11-gl' : 'glmark2', |
| 'x11-glesv2' : 'glmark2-es2', |
| } |
| FLAVORS_STR = ", ".join(sorted(list(FLAVORS) + ['all-linux', 'all-win32'])) |
| |
| def linux_flavors(): |
| return [f for f in FLAVORS.keys() if not f.startswith('win32')] |
| |
| def win32_flavors(): |
| return [f for f in FLAVORS.keys() if f.startswith('win32')] |
| |
| def option_list_cb(option, opt, value, parser): |
| value = value.split(',') |
| setattr(parser.values, option.dest, value) |
| |
| def list_contains(lst, token): |
| for e in lst: |
| if token.endswith('$'): |
| if e.endswith(token[:-1]): return True |
| elif token in e: return True |
| |
| return False |
| |
| def options(opt): |
| opt.load('gnu_dirs') |
| opt.load('compiler_c') |
| opt.load('compiler_cxx') |
| |
| opt.add_option('--with-flavors', type = 'string', action='callback', |
| callback=option_list_cb, |
| dest = 'flavors', |
| help = "a list of flavors to build (%s, all-linux (except dispmanx-glesv2), all-win32)" % FLAVORS_STR) |
| opt.parser.set_default('flavors', []) |
| |
| opt.parser.add_option('--version-suffix', type='string', action='store', dest='versionsuffix', |
| default='', help='add a suffix to the version number') |
| |
| opt.add_option('--no-debug', action='store_false', dest = 'debug', |
| default = True, help='disable compiler debug information') |
| opt.add_option('--no-opt', action='store_false', dest = 'opt', |
| default = True, help='disable compiler optimizations') |
| opt.add_option('--data-path', action='store', dest = 'data_path', |
| help='path to main data (also see --data(root)dir)') |
| opt.add_option('--extras-path', action='store', dest = 'extras_path', |
| help='path to additional data (models, shaders, textures)') |
| |
| def get_data_path(ctx): |
| if ctx.options.data_path is not None: |
| return ctx.options.data_path |
| else: |
| return os.path.join(ctx.env.DATADIR, 'glmark2') |
| |
| def configure(ctx): |
| # Special 'all' flavor |
| if 'all-linux' in ctx.options.flavors: |
| ctx.options.flavors = list(set(ctx.options.flavors) | set(linux_flavors())) |
| ctx.options.flavors.remove('all-linux') |
| # dispmanx is a special case, we don't want to include it in all |
| ctx.options.flavors.remove('dispmanx-glesv2') |
| |
| if 'all-win32' in ctx.options.flavors: |
| ctx.options.flavors = list(set(ctx.options.flavors) | set(win32_flavors())) |
| ctx.options.flavors.remove('all-win32') |
| |
| is_win = any(True for f in win32_flavors() if f in ctx.options.flavors) |
| is_linux = any(True for f in linux_flavors() if f in ctx.options.flavors) |
| |
| if is_win and is_linux: |
| ctx.fatal('Simultaneous Windows and Linux builds are not supported') |
| |
| # Ensure the flavors are valid |
| for flavor in ctx.options.flavors: |
| if flavor not in FLAVORS: |
| ctx.fatal('Unknown flavor: %s. Supported flavors are %s' % (flavor, FLAVORS_STR)) |
| |
| if not ctx.options.flavors: |
| ctx.fatal('You need to select at least one flavor with --with-flavors=flavor1[,flavor2]...\n' + |
| 'Supported flavors are %s' % FLAVORS_STR) |
| |
| for flavor in FLAVORS: |
| if flavor in ctx.options.flavors: |
| ctx.env["FLAVOR_%s" % flavor.upper().replace('-','_')] = FLAVORS[flavor] |
| |
| ctx.load('gnu_dirs') |
| ctx.load('compiler_c') |
| ctx.load('compiler_cxx') |
| |
| if is_win: |
| configure_win32(ctx) |
| else: |
| configure_linux(ctx) |
| |
| ctx.env.append_unique('DEFINES', 'GLMARK_VERSION="%s"' % (VERSION + ctx.options.versionsuffix)) |
| ctx.env.GLMARK2_VERSION = (VERSION + ctx.options.versionsuffix) |
| |
| ctx.msg("Prefix", ctx.env.PREFIX, color = 'PINK') |
| ctx.msg("Data path", get_data_path(ctx), color = 'PINK') |
| ctx.msg("Including extras", "Yes" if ctx.env.HAVE_EXTRAS else "No", |
| color = 'PINK'); |
| if ctx.env.HAVE_EXTRAS: |
| ctx.msg("Extras path", ctx.options.extras_path, color = 'PINK') |
| ctx.msg("Building flavors", ctx.options.flavors) |
| |
| |
| def configure_win32(ctx): |
| # Check required headers |
| req_headers = ['stdlib.h', 'string.h', 'stdint.h', 'stdio.h', 'windows.h'] |
| for header in req_headers: |
| ctx.check_cc(header_name = header, auto_add_header_name = True, mandatory = True) |
| |
| req_libs = [('user32', 'user32'), ('opengl32', 'opengl32'), ('gdi32', 'gdi32')] |
| for (lib, uselib) in req_libs: |
| ctx.check_cc(lib = lib, uselib_store = uselib) |
| |
| # Prepend CXX flags so that they can be overriden by the |
| # CXXFLAGS environment variable |
| if ctx.options.opt: |
| ctx.env.prepend_value('CXXFLAGS', '-O2') |
| if ctx.env.CXX_NAME != 'msvc': |
| if ctx.options.debug: |
| ctx.env.prepend_value('CXXFLAGS', '-g') |
| ctx.env.prepend_value('CXXFLAGS', '-std=c++14 -Wall -Wextra -Wnon-virtual-dtor'.split(' ')) |
| else: |
| ctx.env.prepend_value('CXXFLAGS', '/EHsc /wd4312'.split(' ')) |
| |
| ctx.env.HAVE_EXTRAS = False |
| if ctx.options.extras_path is not None: |
| ctx.env.HAVE_EXTRAS = True |
| ctx.env.append_unique('GLMARK_EXTRAS_PATH', ctx.options.extras_path) |
| ctx.env.append_unique('DEFINES', 'GLMARK_EXTRAS_PATH="%s"' % ctx.options.extras_path) |
| |
| data_path = get_data_path(ctx) |
| |
| # Necessary for M_PI |
| ctx.env.append_unique('DEFINES', '_USE_MATH_DEFINES') |
| ctx.env.append_unique('DEFINES', 'WIN32') |
| # String contants have issues with Windows slashes |
| ctx.env.append_unique('DEFINES', 'GLMARK_DATA_PATH="%s"' % data_path.replace('\\', '/')) |
| ctx.env.append_unique('GLMARK_DATA_PATH', data_path) |
| |
| |
| def configure_linux(ctx): |
| # Check required headers |
| req_headers = ['stdlib.h', 'string.h', 'stdint.h', 'stdio.h', 'dlfcn.h', |
| 'unistd.h', 'jpeglib.h', 'math.h', 'string.h'] |
| for header in req_headers: |
| ctx.check_cc(header_name = header, auto_add_header_name = True, mandatory = True) |
| |
| # Check for required libs |
| req_libs = [('m', 'm'), ('jpeg', 'jpeg')] |
| for (lib, uselib) in req_libs: |
| ctx.check_cc(lib = lib, uselib_store = uselib) |
| |
| # Check for required functions. Note that headers from req_headers |
| # are already included for this check. |
| ctx.check_cc(function_name = 'memset', mandatory = True) |
| # Special test code for sqrt, to make clang/libc++ happy. |
| ctx.check_cc(fragment = 'int main(void) { double (*p)(double); p = sqrt; }', |
| msg = 'Checking for function sqrt', |
| uselib = ['m'], mandatory = True) |
| |
| # Check for a supported version of libpng |
| have_png = False |
| supp_png_pkgs = (('libpng12', '1.2'), ('libpng15', '1.5'), ('libpng16', '1.6'),) |
| for (pkg, atleast) in supp_png_pkgs: |
| try: |
| pkg_ver = ctx.check_cfg(package=pkg, uselib_store='libpng', atleast_version=atleast, |
| args = ['--cflags', '--libs']) |
| except: |
| continue |
| else: |
| have_png = True |
| break |
| |
| if not have_png: |
| ctx.fatal('You need to install a supported version of libpng: ' + str(supp_png_pkgs)) |
| |
| dispmanx = 'dispmanx-glesv2' in ctx.options.flavors |
| if dispmanx: |
| # dispmanx uses custom Broadcom libraries that don't follow standard |
| # Linux packaging. Just force the library setup here. |
| if len(ctx.options.flavors) != 1: |
| ctx.fatal("dispmanx can't be built with any other flavor") |
| |
| ctx.env.append_value('CXXFLAGS', '-I/opt/vc/include') |
| |
| ctx.check_cxx(lib = 'brcmGLESv2', uselib_store = 'glesv2', libpath='/opt/vc/lib') |
| ctx.check_cxx(lib = ['brcmEGL', 'brcmGLESv2'], uselib_store = 'egl', libpath='/opt/vc/lib') |
| ctx.check_cxx(lib = ['bcm_host', 'vcos', 'vchiq_arm'], uselib_store = 'dispmanx', libpath='/opt/vc/lib') |
| |
| # Check optional packages |
| opt_pkgs = [('x11', 'x11', None, list_contains(ctx.options.flavors, 'x11')), |
| ('libdrm','drm', None, list_contains(ctx.options.flavors, 'drm')), |
| ('gbm','gbm', None, list_contains(ctx.options.flavors, 'drm')), |
| ('libudev', 'udev', None, list_contains(ctx.options.flavors, 'drm')), |
| ('mirclient','mirclient', '0.13', list_contains(ctx.options.flavors, 'mir')), |
| ('wayland-client','wayland-client', None, list_contains(ctx.options.flavors, 'wayland')), |
| ('wayland-egl','wayland-egl', None, list_contains(ctx.options.flavors, 'wayland'))] |
| for (pkg, uselib, atleast, mandatory) in opt_pkgs: |
| if atleast is None: |
| ctx.check_cfg(package = pkg, uselib_store = uselib, |
| args = '--cflags --libs', mandatory = mandatory) |
| else: |
| ctx.check_cfg(package = pkg, uselib_store = uselib, atleast_version=atleast, |
| args = '--cflags --libs', mandatory = mandatory) |
| |
| if list_contains(ctx.options.flavors, 'wayland'): |
| # wayland-protocols >= 1.12 required for xdg-shell stable |
| ctx.check_cfg(package = 'wayland-protocols', atleast_version = '1.12', |
| variables = ['pkgdatadir'], uselib_store = 'WAYLAND_PROTOCOLS') |
| ctx.check_cfg(package = 'wayland-scanner', variables = ['wayland_scanner'], |
| uselib_store = 'WAYLAND_SCANNER') |
| |
| # Prepend CXX flags so that they can be overriden by the |
| # CXXFLAGS environment variable |
| if ctx.options.opt: |
| ctx.env.prepend_value('CXXFLAGS', '-O2') |
| if ctx.options.debug: |
| ctx.env.prepend_value('CXXFLAGS', '-g') |
| ctx.env.prepend_value('CXXFLAGS', '-std=c++14 -Wall -Wextra -Wnon-virtual-dtor'.split(' ')) |
| |
| ctx.env.HAVE_EXTRAS = False |
| if ctx.options.extras_path is not None: |
| ctx.env.HAVE_EXTRAS = True |
| ctx.env.append_unique('GLMARK_EXTRAS_PATH', ctx.options.extras_path) |
| ctx.env.append_unique('DEFINES', 'GLMARK_EXTRAS_PATH="%s"' % ctx.options.extras_path) |
| |
| data_path = get_data_path(ctx) |
| |
| ctx.env.append_unique('DEFINES', 'GLMARK_DATA_PATH="%s"' % data_path) |
| ctx.env.append_unique('GLMARK_DATA_PATH', data_path) |
| |
| def build(ctx): |
| ctx.recurse('src') |
| ctx.recurse('data') |
| ctx.recurse('doc') |
| |
| class Glmark2Dist(Context.Context): |
| """ Custom dist command that preserves symbolic links""" |
| |
| cmd = "dist" |
| |
| def execute(self): |
| self.recurse([os.path.dirname(Context.g_module.root_path)]) |
| self.archive() |
| |
| def get_files(self): |
| import fnmatch |
| files = [] |
| excludes = ['*.bzr', '*.git', '*~', './.*waf*', './build*', '*.swp', '*.pyc', '*glmark2-*.tar.gz'] |
| for (dirpath, dirnames, filenames) in os.walk(top): |
| names_to_remove = [] |
| names = dirnames + filenames |
| for n in names: |
| for exclude in excludes: |
| if fnmatch.fnmatch(os.path.join(dirpath, n), exclude): |
| names_to_remove.append(n) |
| break |
| |
| for d in names_to_remove: |
| if d in dirnames: |
| dirnames.remove(d) |
| if d in filenames: |
| filenames.remove(d) |
| |
| files.extend([os.path.join(dirpath, d) for d in dirnames]) |
| files.extend([os.path.join(dirpath, f) for f in filenames]) |
| |
| return files |
| |
| def archive(self): |
| import tarfile |
| tar = tarfile.open(APPNAME + '-' + VERSION + '.tar.gz', 'w:gz') |
| for f in self.get_files(): |
| tar.add(f, arcname = APPNAME + '-' + VERSION + '/' + f, recursive = False) |
| tar.close() |