summaryrefslogtreecommitdiffstats
path: root/waftools
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-07-16 13:28:28 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2013-11-21 21:22:36 +0100
commit7e2edad8efea55e8df1faa695d1389ef4e326d7c (patch)
treef9662620b8ecaf50f6c67804dd0d99d00d85fe5b /waftools
parent0cb9227a73f03a6ecdf71e837c7c33c823b194b4 (diff)
downloadmpv-7e2edad8efea55e8df1faa695d1389ef4e326d7c.tar.bz2
mpv-7e2edad8efea55e8df1faa695d1389ef4e326d7c.tar.xz
switch the build system to waf
This commit adds a new build system based on waf. configure and Makefile are deprecated effective immediately and someday in the future they will be removed (they are still available by running ./old-configure). You can find how the choice for waf came to be in `DOCS/waf-buildsystem.rst`. TL;DR: we couldn't get the same level of abstraction and customization with other build systems we tried (CMake and autotools). For guidance on how to build the software now, take a look at README.md and the cross compilation guide. CREDITS: This is a squash of ~250 commits. Some of them are not by me, so here is the deserved attribution: - @wm4 contributed some Windows fixes, renamed configure to old-configure and contributed to the bootstrap script. Also, GNU/Linux testing. - @lachs0r contributed some Windows fixes and the bootstrap script. - @Nikoli contributed a lot of testing and discovered many bugs. - @CrimsonVoid contributed changes to the bootstrap script.
Diffstat (limited to 'waftools')
-rw-r--r--waftools/__init__.py2
-rw-r--r--waftools/checks/__init__.py0
-rw-r--r--waftools/checks/custom.py119
-rw-r--r--waftools/checks/generic.py134
-rw-r--r--waftools/dependencies.py210
-rw-r--r--waftools/detections/__init__.py0
-rw-r--r--waftools/detections/compiler.py57
-rw-r--r--waftools/detections/cpu.py28
-rw-r--r--waftools/detections/devices.py29
-rw-r--r--waftools/features.py69
-rw-r--r--waftools/fragments/cocoa.m11
-rw-r--r--waftools/fragments/coreaudio.c15
-rw-r--r--waftools/fragments/dvb.c10
-rw-r--r--waftools/fragments/ebx.c12
-rw-r--r--waftools/fragments/gl_x11.c9
-rw-r--r--waftools/fragments/iconv.c30
-rw-r--r--waftools/fragments/libavfilter.c7
-rw-r--r--waftools/fragments/lua.c24
-rw-r--r--waftools/fragments/lua_libquvi4.c3
-rw-r--r--waftools/fragments/lua_libquvi9.c3
-rw-r--r--waftools/fragments/mng.c7
-rw-r--r--waftools/fragments/oss_audio.c11
-rw-r--r--waftools/fragments/oss_audio_header.c13
-rw-r--r--waftools/fragments/pthreads.c10
-rw-r--r--waftools/fragments/pvr.c7
-rw-r--r--waftools/fragments/vcd_windows.c7
-rw-r--r--waftools/fragments/wasapi.c19
-rw-r--r--waftools/fragments/xf86vm.c8
-rw-r--r--waftools/fragments/xf86xk.c6
-rw-r--r--waftools/generators/__init__.py0
-rw-r--r--waftools/generators/headers.py36
-rw-r--r--waftools/generators/sources.py37
-rw-r--r--waftools/inflectors.py26
-rw-r--r--waftools/waf_customizations.py46
34 files changed, 1005 insertions, 0 deletions
diff --git a/waftools/__init__.py b/waftools/__init__.py
new file mode 100644
index 0000000000..6f804bce35
--- /dev/null
+++ b/waftools/__init__.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+# encoding: utf-8
diff --git a/waftools/checks/__init__.py b/waftools/checks/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/waftools/checks/__init__.py
diff --git a/waftools/checks/custom.py b/waftools/checks/custom.py
new file mode 100644
index 0000000000..d2da024037
--- /dev/null
+++ b/waftools/checks/custom.py
@@ -0,0 +1,119 @@
+from waftools.checks.generic import *
+
+__all__ = ["check_pthreads", "check_iconv", "check_lua", "check_oss"]
+
+pthreads_program = load_fragment('pthreads.c')
+
+def check_pthreads(ctx, dependency_identifier):
+ platform_cflags = {
+ 'linux': '-D_REENTRANT',
+ 'freebsd': '-D_THREAD_SAFE',
+ 'netbsd': '-D_THREAD_SAFE',
+ 'openbsd': '-D_THREAD_SAFE',
+ 'win32': '-DPTW32_STATIC_LIB',
+ }.get(ctx.env.DEST_OS, '')
+ libs = ['pthreadGC2', 'pthread']
+ checkfn = check_cc(fragment=pthreads_program, cflags=platform_cflags)
+ return check_libs(libs, checkfn)(ctx, dependency_identifier)
+
+def check_iconv(ctx, dependency_identifier):
+ iconv_program = load_fragment('iconv.c')
+ libdliconv = " ".join(ctx.env.LIB_LIBDL + ['iconv'])
+ libs = ['iconv', libdliconv]
+ checkfn = check_cc(fragment=iconv_program)
+ return check_libs(libs, checkfn)(ctx, dependency_identifier)
+
+def check_lua(ctx, dependency_identifier):
+ if 'libquvi4' in ctx.env.satisfied_deps:
+ additional_lua_test_header = '#include <quvi/quvi.h>'
+ additional_lua_test_code = load_fragment('lua_libquvi4.c')
+ elif 'libquvi9' in ctx.env.satisfied_deps:
+ additional_lua_test_header = '#include <quvi.h>'
+ additional_lua_test_code = load_fragment('lua_libquvi9.c')
+ else:
+ additional_lua_test_header = ''
+ additional_lua_test_code = ''
+
+ fragment = load_fragment('lua.c').format(
+ additional_lua_test_header='',
+ additional_lua_test_code='')
+
+ lua_versions = [
+ ( '51', 'lua >= 5.1.0 lua < 5.2.0'),
+ ( '51deb', 'lua5.1 >= 5.1.0'), # debian
+ ( 'luajit', 'luajit >= 2.0.0' ),
+ # assume all our dependencies (libquvi in particular) link with 5.1
+ ( '52', 'lua >= 5.2.0' ),
+ ( '52deb', 'lua5.2 >= 5.2.0'), # debian
+ ]
+
+ if ctx.options.LUA_VER:
+ lua_versions = \
+ [lv for lv in lua_versions if lv[0] == ctx.options.LUA_VER]
+
+ for lua_version, pkgconfig_query in lua_versions:
+ if compose_checks(
+ check_pkg_config(pkgconfig_query, uselib_store=lua_version),
+ check_cc(fragment=fragment, use=lua_version))\
+ (ctx, dependency_identifier):
+ # XXX: this is a bit of a hack, ask waf developers if I can copy
+ # the uselib_store to 'lua'
+ ctx.mark_satisfied(lua_version)
+ ctx.add_optional_message(dependency_identifier,
+ 'version found: ' + lua_version)
+ return True
+ return False
+
+# from here on there is the OSS check.. just stop reading here unless you want
+# to die inside a little
+def __fail_oss_check__(ctx):
+ ctx.define('PATH_DEV_DSP', '')
+ ctx.define('PATH_DEV_MIXER', '')
+ return False
+
+def __get_osslibdir__():
+ try:
+ cmd = ['sh', '-c', "'source /etc/oss.conf && echo $OSSLIBDIR'"]
+ p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE,
+ stdout=Utils.subprocess.PIPE,
+ stderr=Utils.subprocess.PIPE)
+ return p.communicate()[0]
+ except Exception:
+ return ""
+
+def __check_oss_headers__(ctx, dependency_identifier):
+ import os
+
+ real_oss = ctx.check_cc(fragment=load_fragment('oss_audio_header.c'),
+ use='soundcard')
+
+ if real_oss:
+ if os.path.exists('/etc/oss.conf'):
+ osslibdir = __get_osslibdir__()
+ ossincdir = os.path.join(osslibdir, 'include')
+ soundcard_h = os.path.join(ossincdir, 'sys', 'soundcard.h')
+ if os.path.exists(soundcard_h):
+ ctx.env.CFLAGS.append('-I{0}'.format(ossincdir))
+
+ return True
+
+def __check_oss_bsd__(ctxdependency_identifier):
+ # add the oss audio library through a check
+ ctx.define('PATH_DEV_DSP', '/dev/sound')
+ if check_cc(lib='ossaudio')(ctx, dependency_identifier):
+ return True
+ else:
+ return __fail_oss_check__(ctx)
+
+def check_oss(ctx, dependency_identifier):
+ func = check_cc(fragment=load_fragment('oss_audio.c'), use='soundcard')
+ if func(ctx, dependency_identifier):
+ ctx.define('PATH_DEV_DSP', '/dev/dsp')
+ ctx.define('PATH_DEV_MIXER', '/dev/mixer')
+
+ if ctx.env.DEST_OS in ['openbsd', 'netbsd']:
+ return __check_oss_bsd_library__(ctx, dependency_identifier)
+ else:
+ return __check_oss_headers__(ctx, dependency_identifier)
+
+ return __fail_oss_check__(ctx)
diff --git a/waftools/checks/generic.py b/waftools/checks/generic.py
new file mode 100644
index 0000000000..46813aed01
--- /dev/null
+++ b/waftools/checks/generic.py
@@ -0,0 +1,134 @@
+import os
+from inflectors import DependencyInflector
+
+__all__ = [
+ "check_pkg_config", "check_cc", "check_statement", "check_libs",
+ "check_headers", "compose_checks", "check_true", "any_version",
+ "load_fragment", "check_stub", "check_ctx_vars"]
+
+any_version = None
+
+def even(n):
+ return n % 2 == 0
+
+def __define_options__(dependency_identifier):
+ return DependencyInflector(dependency_identifier).define_dict()
+
+def __merge_options__(dependency_identifier, *args):
+ options_accu = DependencyInflector(dependency_identifier).storage_dict()
+ options_accu['mandatory'] = False
+ [options_accu.update(arg) for arg in args if arg]
+ return options_accu
+
+
+def check_libs(libs, function):
+ libs = [None] + libs
+ def fn(ctx, dependency_identifier):
+ for lib in libs:
+ kwargs = lib and {'lib': lib} or {}
+ if function(ctx, dependency_identifier, **kwargs):
+ return True
+ return False
+ return fn
+
+def check_statement(header, statement, **kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ fragment = """
+ #include <{0}>
+ int main(int argc, char **argv)
+ {{ {1}; return 0; }} """.format(header, statement)
+ opts = __merge_options__(dependency_identifier,
+ {'fragment':fragment},
+ __define_options__(dependency_identifier),
+ kw_ext, kw)
+ return ctx.check_cc(**opts)
+ return fn
+
+def check_cc(**kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ options = __merge_options__(dependency_identifier,
+ __define_options__(dependency_identifier),
+ kw_ext, kw)
+ return ctx.check_cc(**options)
+ return fn
+
+def check_pkg_config(*args, **kw_ext):
+ def fn(ctx, dependency_identifier, **kw):
+ argsl = list(args)
+ packages = [el for (i, el) in enumerate(args) if even(i)]
+ sargs = [i for i in args if i] # remove None
+ pkgc_args = ["--libs", "--cflags"]
+ if ctx.dependency_satisfied('static-build'):
+ pkgc_args += ["--static"]
+
+ defaults = {
+ 'path': ctx.env.PKG_CONFIG,
+ 'package': " ".join(packages),
+ 'args': sargs + pkgc_args }
+ opts = __merge_options__(dependency_identifier, defaults, kw_ext, kw)
+ if ctx.check_cfg(**opts):
+ return True
+ else:
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.undefine(defkey)
+ return False
+ return fn
+
+def check_headers(*headers):
+ def undef_others(ctx, headers, found):
+ not_found_hs = set(headers) - set([found])
+ for not_found_h in not_found_hs:
+ defkey = DependencyInflector(not_found_h).define_key()
+ ctx.undefine(defkey)
+
+ def fn(ctx, dependency_identifier):
+ for header in headers:
+ defaults = {'header_name': header, 'features': 'c cprogram'}
+ options = __merge_options__(dependency_identifier, defaults)
+ if ctx.check(**options):
+ undef_others(ctx, headers, header)
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.define(defkey, 1)
+ return True
+ undef_others(ctx, headers, None)
+ return False
+ return fn
+
+def check_true(ctx, dependency_identifier):
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.define(defkey, 1)
+ return True
+
+def check_ctx_vars(*variables):
+ def fn(ctx, dependency_identifier):
+ missing = []
+ for variable in variables:
+ if variable not in ctx.env:
+ missing.append(variable)
+
+ if any(missing):
+ ctx.add_optional_message(dependency_identifier,
+ 'missing {0}'.format(', '.join(missing)))
+ return False
+ else:
+ return True
+
+ return fn
+
+def check_stub(ctx, dependency_identifier):
+ defkey = DependencyInflector(dependency_identifier).define_key()
+ ctx.undefine(defkey)
+ return False
+
+def compose_checks(*checks):
+ def fn(ctx, dependency_identifier):
+ return all([check(ctx, dependency_identifier) for check in checks])
+ return fn
+
+def load_fragment(fragment):
+ file_path = os.path.join(os.path.dirname(__file__), '..', 'fragments',
+ fragment)
+ fp = open(file_path,"r")
+ fragment_code = fp.read()
+ fp.close()
+ return fragment_code
diff --git a/waftools/dependencies.py b/waftools/dependencies.py
new file mode 100644
index 0000000000..cd85180fae
--- /dev/null
+++ b/waftools/dependencies.py
@@ -0,0 +1,210 @@
+from waflib.Errors import ConfigurationError, WafError
+from waflib.Configure import conf
+from waflib.Build import BuildContext
+from waflib.Logs import pprint
+from inflectors import DependencyInflector
+
+class DependencyError(Exception):
+ pass
+
+class Dependency(object):
+ def __init__(self, ctx, known_deps, satisfied_deps, dependency):
+ self.ctx = ctx
+ self.known_deps = known_deps
+ self.satisfied_deps = satisfied_deps
+ self.identifier, self.desc = dependency['name'], dependency['desc']
+ self.attributes = self.__parse_attributes__(dependency)
+
+ ctx.env.known_deps.add(self.identifier)
+ for dep_key in ['deps', 'deps_any', 'deps_neg']:
+ if dep_key in self.attributes:
+ deps = self.attributes[dep_key]
+ self.ctx.ensure_dependency_is_known(*deps)
+
+
+ def __parse_attributes__(self, dependency):
+ if 'os_specific_checks' in dependency:
+ all_chks = dependency['os_specific_checks']
+ chks = [check for check in all_chks if check in self.satisfied_deps]
+ if any(chks):
+ return all_chks[chks[0]]
+ return dependency
+
+ def check(self):
+ self.ctx.start_msg('Checking for {0}'.format(self.desc))
+
+ try:
+ self.check_disabled()
+ self.check_any_dependencies()
+ self.check_dependencies()
+ self.check_negative_dependencies()
+ except DependencyError:
+ # No check was run, since the prerequisites of the dependency are
+ # not satisfied. Make sure the define is 'undefined' so that we
+ # get a `#define YYY 0` in `config.h`.
+ def_key = DependencyInflector(self.identifier).define_key()
+ self.ctx.undefine(def_key)
+ self.fatal_if_needed()
+ return
+
+ self.check_autodetect_func()
+
+ def check_disabled(self):
+ if self.enabled_option() == False:
+ self.skip()
+ raise DependencyError
+
+ if self.enabled_option() == True:
+ self.attributes['req'] = True
+ self.attributes['fmsg'] = "You manually enabled the feature '{0}', but \
+the autodetection check failed.".format(self.identifier)
+
+ def check_any_dependencies(self):
+ if 'deps_any' in self.attributes:
+ deps = set(self.attributes['deps_any'])
+ if len(deps & self.satisfied_deps) == 0:
+ self.skip("not found any of {0}".format(", ".join(deps)))
+ raise DependencyError
+
+ def check_dependencies(self):
+ if 'deps' in self.attributes:
+ deps = set(self.attributes['deps'])
+ if not deps <= self.satisfied_deps:
+ missing_deps = deps - self.satisfied_deps
+ self.skip("{0} not found".format(", ".join(missing_deps)))
+ raise DependencyError
+
+ def check_negative_dependencies(self):
+ if 'deps_neg' in self.attributes:
+ deps = set(self.attributes['deps_neg'])
+ if deps <= self.satisfied_deps:
+ conflicting_deps = deps & self.satisfied_deps
+ self.skip("{0} found".format(", ".join(conflicting_deps)), 'CYAN')
+ raise DependencyError
+
+ def check_autodetect_func(self):
+ if self.attributes['func'](self.ctx, self.identifier):
+ self.success(self.identifier)
+ else:
+ self.fail()
+ self.fatal_if_needed()
+
+ def enabled_option(self):
+ try:
+ return getattr(self.ctx.options, self.enabled_option_repr())
+ except AttributeError:
+ pass
+ return None
+
+ def enabled_option_repr(self):
+ return "enable_{0}".format(self.identifier)
+
+ def success(self, depname):
+ self.ctx.mark_satisfied(depname)
+ self.ctx.end_msg(self.__message__('yes'))
+
+ def fail(self, reason='no'):
+ self.ctx.end_msg(self.__message__(reason), 'RED')
+
+ def fatal_if_needed(self):
+ if self.enabled_option() == False:
+ return
+ if self.attributes.get('req', False):
+ raise ConfigurationError(self.attributes['fmsg'])
+
+ def skip(self, reason='disabled', color='YELLOW'):
+ self.ctx.end_msg(self.__message__(reason), color)
+
+ def __message__(self, message):
+ optional_message = self.ctx.deps_msg.get(self.identifier)
+ if optional_message:
+ return "{0} ({1})".format(message, optional_message)
+ else:
+ return message
+
+def configure(ctx):
+ def __detect_target_os_dependency__(ctx):
+ target = "os-{0}".format(ctx.env.DEST_OS)
+ ctx.start_msg('Detected target OS:')
+ ctx.end_msg(target)
+ ctx.env.known_deps.add(target)
+ ctx.env.satisfied_deps.add(target)
+
+ ctx.deps_msg = {}
+ ctx.env['known_deps'] = set()
+ ctx.env['satisfied_deps'] = set()
+ __detect_target_os_dependency__(ctx)
+
+@conf
+def ensure_dependency_is_known(ctx, *depnames):
+ deps = set([d for d in depnames if not d.startswith('os-')])
+ if not deps <= ctx.env.known_deps:
+ raise ConfigurationError(
+ "error in dependencies definition: some dependencies in"
+ " {0} are unknown.".format(deps))
+
+
+@conf
+def mark_satisfied(ctx, dependency_identifier):
+ ctx.env.satisfied_deps.add(dependency_identifier)
+
+@conf
+def add_optional_message(ctx, dependency_identifier, message):
+ ctx.deps_msg[dependency_identifier] = message
+
+@conf
+def parse_dependencies(ctx, dependencies):
+ def __check_dependency__(ctx, dependency):
+ Dependency(ctx,
+ ctx.env.known_deps,
+ ctx.env.satisfied_deps,
+ dependency).check()
+
+ [__check_dependency__(ctx, dependency) for dependency in dependencies]
+
+@conf
+def dependency_satisfied(ctx, dependency_identifier):
+ ctx.ensure_dependency_is_known(dependency_identifier)
+ return dependency_identifier in ctx.env.satisfied_deps
+
+def filtered_sources(ctx, sources):
+ def __source_file__(source):
+ if isinstance(source, tuple):
+ return source[0]
+ else:
+ return source
+
+ def __check_filter__(dependency):
+ if dependency.find('!') == 0:
+ dependency = dependency.lstrip('!')
+ ctx.ensure_dependency_is_known(dependency)
+ return dependency not in ctx.env.satisfied_deps
+ else:
+ ctx.ensure_dependency_is_known(dependency)
+ return dependency in ctx.env.satisfied_deps
+
+ def __unpack_and_check_filter__(source):
+ try:
+ _, dependency = source
+ return __check_filter__(dependency)
+ except ValueError:
+ return True
+
+ return [__source_file__(source) for source in sources \
+ if __unpack_and_check_filter__(source)]
+
+def env_fetch(tx):
+ def fn(ctx):
+ deps = list(ctx.env.satisfied_deps)
+ lists = [ctx.env[tx(dep)] for dep in deps if (tx(dep) in ctx.env)]
+ return [item for sublist in lists for item in sublist]
+ return fn
+
+def dependencies_use(ctx):
+ return [DependencyInflector(dep).storage_key() for \
+ dep in ctx.env.satisfied_deps]
+
+BuildContext.filtered_sources = filtered_sources
+BuildContext.dependencies_use = dependencies_use
+BuildContext.dependencies_includes = env_fetch(lambda x: "INCLUDES_{0}".format(x))
+BuildContext.dependency_satisfied = dependency_satisfied
diff --git a/waftools/detections/__init__.py b/waftools/detections/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/waftools/detections/__init__.py
diff --git a/waftools/detections/compiler.py b/waftools/detections/compiler.py
new file mode 100644
index 0000000000..1fee446409
--- /dev/null
+++ b/waftools/detections/compiler.py
@@ -0,0 +1,57 @@
+from waflib import Utils
+
+def __get_cc_env_vars__(cc):
+ cmd = cc + ['-dM', '-E', '-']
+ try:
+ p = Utils.subprocess.Popen(cmd, stdin=Utils.subprocess.PIPE,
+ stdout=Utils.subprocess.PIPE,
+ stderr=Utils.subprocess.PIPE)
+ p.stdin.write('\n'.encode())
+ return p.communicate()[0]
+ except Exception:
+ return ""
+
+def __add_generic_flags__(ctx):
+ ctx.env.CFLAGS += ["-D_ISOC99_SOURCE", "-D_GNU_SOURCE",
+ "-D_LARGEFILE_SOURCE", "-D_FILE_OFFSET_BITS=64",
+ "-D_LARGEFILE64_SOURCE",
+ "-std=gnu99", "-Wall"]
+
+ if ctx.is_debug_build():
+ ctx.env.CFLAGS += ['-g']
+
+def __add_gcc_flags__(ctx):
+ ctx.env.CFLAGS += ["-Wundef", "-Wmissing-prototypes",
+ "-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
+ "-Wredundant-decls", "-Wno-pointer-sign",
+ "-Werror=implicit-function-declaration",
+ "-Wno-error=deprecated-declarations",
+ "-Wno-error=unused-function" ]
+
+def __add_clang_flags__(ctx):
+ ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics"]
+
+def __add_mingw_flags__(ctx):
+ ctx.env.CFLAGS += ['-D__USE_MINGW_ANSI_STDIO=1']
+ ctx.env.CFLAGS += ['-DBYTE_ORDER=1234']
+ ctx.env.CFLAGS += ['-DLITLE_ENDIAN=1234']
+ ctx.env.CFLAGS += ['-DBIG_ENDIAN=4321']
+ ctx.env.LAST_LINKFLAGS += ['-mconsole']
+
+__compiler_map__ = {
+ '__GNUC__': __add_gcc_flags__,
+ '__clang__': __add_clang_flags__,
+ '__MINGW32__': __add_mingw_flags__,
+}
+
+def __apply_map__(ctx, fnmap):
+ if 'CC_ENV_VARS' not in ctx.env:
+ ctx.env.CC_ENV_VARS = str(__get_cc_env_vars__(ctx.env.CC))
+ for k, fn in fnmap.items():
+ if ctx.env.CC_ENV_VARS.find(k) > 0:
+ fn(ctx)
+
+def configure(ctx):
+ __add_generic_flags__(ctx)
+ __apply_map__(ctx, __compiler_map__)
+
diff --git a/waftools/detections/cpu.py b/waftools/detections/cpu.py
new file mode 100644
index 0000000000..ce342fdd73
--- /dev/null
+++ b/waftools/detections/cpu.py
@@ -0,0 +1,28 @@
+def x86(ctx):
+ ctx.define('ARCH_X86', 1)
+ ctx.define('ARCH_X86_32', 1)
+
+def x86_64(ctx):
+ ctx.define('ARCH_X86', 1)
+ ctx.define('ARCH_X86_64', 1)
+ ctx.define('HAVE_FAST_64BIT', 1)
+
+def ia64(ctx):
+ ctx.define('HAVE_FAST_64BIT', 1)
+
+def default(ctx):
+ pass
+
+def configure(ctx):
+ ctx.define('ARCH_X86', 0)
+ ctx.define('ARCH_X86_32', 0)
+ ctx.define('ARCH_X86_64', 0)
+ ctx.define('HAVE_FAST_64BIT', 0)
+
+ ctx.define('HAVE_MMX', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_MMX2', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSE', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSE2', 'ARCH_X86', quote=False)
+ ctx.define('HAVE_SSSE3', 'ARCH_X86', quote=False)
+
+ globals().get(ctx.env.DEST_CPU, default)(ctx)
diff --git a/waftools/detections/devices.py b/waftools/detections/devices.py
new file mode 100644
index 0000000000..2533788691
--- /dev/null
+++ b/waftools/detections/devices.py
@@ -0,0 +1,29 @@
+__cdrom_devices_map__ = {
+ 'win32': 'D:',
+ 'cygwin': 'D:',
+ 'darwin': '/dev/disk1',
+ 'freebsd': '/dev/cd0',
+ 'openbsd': '/dev/rcd0r',
+ 'default': '/dev/cdrom'
+}
+
+__dvd_devices_map__ = {
+ 'win32': 'D:',
+ 'cygwin': 'D:',
+ 'darwin': '/dev/rdiskN',
+ 'freebsd': '/dev/cd0',
+ 'openbsd': '/dev/rcd0r',
+ 'default': '/dev/dvd'
+}
+
+def __default_cdrom_device__(ctx):
+ default = __cdrom_devices_map__['default']
+ return __cdrom_devices_map__.get(ctx.env.DEST_OS, default)
+
+def __default_dvd_device__(ctx):
+ default = __dvd_devices_map__['default']
+ return __dvd_devices_map__.get(ctx.env.DEST_OS, default)
+
+def configure(ctx):
+ ctx.define('DEFAULT_DVD_DEVICE', __default_dvd_device__(ctx))
+ ctx.define('DEFAULT_CDROM_DEVICE', __default_cdrom_device__(ctx))
diff --git a/waftools/features.py b/waftools/features.py
new file mode 100644
index 0000000000..1385d41dbf
--- /dev/null
+++ b/waftools/features.py
@@ -0,0 +1,69 @@
+from waflib.Options import OptionsContext
+
+class Feature(object):
+ def __init__(self, group, feature):
+ self.group = group
+ self.identifier, self.attributes = feature['name'], feature
+
+ def add_options(self):
+ [self.add_option(option_rule) for option_rule in self.option_rules()]
+
+ def add_option(self, rule):
+ self.group.add_option(self.option(rule['state']),
+ action=rule['action'],
+ default=rule['default'],
+ dest=self.storage(),
+ help=self.help(rule['state']))
+
+ # private
+ def option_rules(self):
+ return {
+ 'autodetect': [
+ {'state': 'disable', 'action': 'store_false', 'default': None},
+ {'state': 'enable', 'action': 'store_true', 'default': None},
+ ],
+ 'disable': [
+ {'state': 'disable', 'action': 'store_false', 'default': False},
+ {'state': 'enable', 'action': 'store_true', 'default': False},
+ ],
+ 'enable': [
+ {'state': 'disable', 'action': 'store_false', 'default': True},
+ ],
+ }[self.behaviour()]
+
+
+ def behaviour(self):
+ if 'default' in self.attributes:
+ return self.attributes['default']
+ else:
+ return 'autodetect'
+
+
+ def option(self, state):
+ return "--{0}-{1}".format(state, self.identifier)
+
+ def help(self, state):
+ return "{0} {1} [{2}]" \
+ .format(state, self.attributes['desc'], self.behaviour())
+
+ def storage(self):
+ return "enable_{0}".format(self.identifier)
+
+def add_feature(group, feature):
+ Feature(group, feature).add_options()
+
+def parse_features(opt, group_name, features):
+ def is_feature(dep):
+ return dep['name'].find('--') >= 0
+
+ def strip_feature(dep):
+ dep['name'] = dep['name'].lstrip('-')
+ return dep
+
+ features = [strip_feature(dep) for dep in features if is_feature(dep)]
+ group = opt.get_option_group(group_name)
+ if not group:
+ group = opt.add_option_group(group_name)
+ [add_feature(group, feature) for feature in features]
+
+OptionsContext.parse_features = parse_features
diff --git a/waftools/fragments/cocoa.m b/waftools/fragments/cocoa.m
new file mode 100644
index 0000000000..6e0e4d32b4
--- /dev/null
+++ b/waftools/fragments/cocoa.m
@@ -0,0 +1,11 @@
+#import <CoreServices/CoreServices.h>
+#import <OpenGL/OpenGL.h>
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char **argv) {
+ @autoreleasepool {
+ NSArray *ary = @[@1, @2, @3];
+ NSLog(@"test subscripting: %@", ary[0]);
+ NSApplicationLoad();
+ }
+}
diff --git a/waftools/fragments/coreaudio.c b/waftools/fragments/coreaudio.c
new file mode 100644
index 0000000000..c7411311a7
--- /dev/null
+++ b/waftools/fragments/coreaudio.c
@@ -0,0 +1,15 @@
+#include <CoreAud