mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
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.
This commit is contained in:
2
waftools/__init__.py
Normal file
2
waftools/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
0
waftools/checks/__init__.py
Normal file
0
waftools/checks/__init__.py
Normal file
119
waftools/checks/custom.py
Normal file
119
waftools/checks/custom.py
Normal file
@@ -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)
|
||||
134
waftools/checks/generic.py
Normal file
134
waftools/checks/generic.py
Normal file
@@ -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
|
||||
210
waftools/dependencies.py
Normal file
210
waftools/dependencies.py
Normal file
@@ -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
|
||||
0
waftools/detections/__init__.py
Normal file
0
waftools/detections/__init__.py
Normal file
57
waftools/detections/compiler.py
Normal file
57
waftools/detections/compiler.py
Normal file
@@ -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__)
|
||||
|
||||
28
waftools/detections/cpu.py
Normal file
28
waftools/detections/cpu.py
Normal file
@@ -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)
|
||||
29
waftools/detections/devices.py
Normal file
29
waftools/detections/devices.py
Normal file
@@ -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))
|
||||
69
waftools/features.py
Normal file
69
waftools/features.py
Normal file
@@ -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
|
||||
11
waftools/fragments/cocoa.m
Normal file
11
waftools/fragments/cocoa.m
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
15
waftools/fragments/coreaudio.c
Normal file
15
waftools/fragments/coreaudio.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AudioComponentDescription desc = (AudioComponentDescription) {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
.componentSubType = kAudioUnitSubType_DefaultOutput,
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
};
|
||||
|
||||
AudioComponentFindNext(NULL, &desc);
|
||||
return 0;
|
||||
}
|
||||
10
waftools/fragments/dvb.c
Normal file
10
waftools/fragments/dvb.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
int main(void) {return 0;}
|
||||
12
waftools/fragments/ebx.c
Normal file
12
waftools/fragments/ebx.c
Normal file
@@ -0,0 +1,12 @@
|
||||
int main(void) {
|
||||
int x;
|
||||
__asm__ volatile(
|
||||
"xor %0, %0"
|
||||
:"=b"(x)
|
||||
// just adding ebx to clobber list seems unreliable with some
|
||||
// compilers, e.g. Haiku's gcc 2.95
|
||||
);
|
||||
// and the above check does not work for OSX 64 bit...
|
||||
__asm__ volatile("":::"%ebx");
|
||||
return 0;
|
||||
}
|
||||
9
waftools/fragments/gl_x11.c
Normal file
9
waftools/fragments/gl_x11.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
glXCreateContext(NULL, NULL, NULL, True);
|
||||
glFinish();
|
||||
return 0;
|
||||
}
|
||||
30
waftools/fragments/iconv.c
Normal file
30
waftools/fragments/iconv.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <iconv.h>
|
||||
#define INBUFSIZE 1024
|
||||
#define OUTBUFSIZE 4096
|
||||
|
||||
char inbuffer[INBUFSIZE];
|
||||
char outbuffer[OUTBUFSIZE];
|
||||
|
||||
int main(void) {
|
||||
size_t numread;
|
||||
iconv_t icdsc;
|
||||
char *tocode="UTF-8";
|
||||
char *fromcode="cp1250";
|
||||
if ((icdsc = iconv_open(tocode, fromcode)) != (iconv_t)(-1)) {
|
||||
while ((numread = read(0, inbuffer, INBUFSIZE))) {
|
||||
char *iptr=inbuffer;
|
||||
char *optr=outbuffer;
|
||||
size_t inleft=numread;
|
||||
size_t outleft=OUTBUFSIZE;
|
||||
if (iconv(icdsc, &iptr, &inleft, &optr, &outleft)
|
||||
!= (size_t)(-1)) {
|
||||
write(1, outbuffer, OUTBUFSIZE - outleft);
|
||||
}
|
||||
}
|
||||
if (iconv_close(icdsc) == -1)
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
7
waftools/fragments/libavfilter.c
Normal file
7
waftools/fragments/libavfilter.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <libavfilter/avfilter.h>
|
||||
void vf_next_query_format() {}
|
||||
int main(void) {
|
||||
avfilter_register_all();
|
||||
vf_next_query_format();
|
||||
return 0;
|
||||
}
|
||||
24
waftools/fragments/lua.c
Normal file
24
waftools/fragments/lua.c
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <stdlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
// filled on the python side with .format()
|
||||
{additional_lua_test_header}
|
||||
|
||||
void test_lua(void) {{
|
||||
lua_State *L = luaL_newstate();
|
||||
lua_pushstring(L, "test");
|
||||
lua_setglobal(L, "test");
|
||||
}}
|
||||
|
||||
void test_other(void) {{
|
||||
// filled on the python side with .format()
|
||||
{additional_lua_test_code}
|
||||
}}
|
||||
|
||||
int main(void) {{
|
||||
test_lua();
|
||||
test_other();
|
||||
return 0;
|
||||
}}
|
||||
3
waftools/fragments/lua_libquvi4.c
Normal file
3
waftools/fragments/lua_libquvi4.c
Normal file
@@ -0,0 +1,3 @@
|
||||
quvi_t q;
|
||||
if (quvi_init(&q) == QUVI_OK)
|
||||
quvi_supported(q, "http://nope");
|
||||
3
waftools/fragments/lua_libquvi9.c
Normal file
3
waftools/fragments/lua_libquvi9.c
Normal file
@@ -0,0 +1,3 @@
|
||||
quvi_t q = quvi_new();
|
||||
if (quvi_ok(q))
|
||||
quvi_supports(q, "http://nope", QUVI_SUPPORTS_MODE_OFFLINE, QUVI_SUPPORTS_TYPE_MEDIA);
|
||||
7
waftools/fragments/mng.c
Normal file
7
waftools/fragments/mng.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <libmng.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char * p_ver = mng_version_text();
|
||||
return !p_ver || p_ver[0] == 0;
|
||||
}
|
||||
11
waftools/fragments/oss_audio.c
Normal file
11
waftools/fragments/oss_audio.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#if HAVE_SOUNDCARD_H
|
||||
#include <soundcard.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_SOUNDCARD_H
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return SNDCTL_DSP_SETFRAGMENT;
|
||||
}
|
||||
13
waftools/fragments/oss_audio_header.c
Normal file
13
waftools/fragments/oss_audio_header.c
Normal file
@@ -0,0 +1,13 @@
|
||||
#if HAVE_SOUNDCARD_H
|
||||
#include <soundcard.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_SOUNDCARD_H
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPEN_SOUND_SYSTEM
|
||||
int main(void) {{ return 0; }}
|
||||
#else
|
||||
#error Not the real thing
|
||||
#endif
|
||||
10
waftools/fragments/pthreads.c
Normal file
10
waftools/fragments/pthreads.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <pthread.h>
|
||||
static void *func(void *arg) { return arg; }
|
||||
int main(void) {
|
||||
pthread_t tid;
|
||||
#ifdef PTW32_STATIC_LIB
|
||||
pthread_win32_process_attach_np();
|
||||
pthread_win32_thread_attach_np();
|
||||
#endif
|
||||
return pthread_create (&tid, 0, func, 0) != 0;
|
||||
}
|
||||
7
waftools/fragments/pvr.c
Normal file
7
waftools/fragments/pvr.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <linux/videodev2.h>
|
||||
int main(void)
|
||||
{
|
||||
struct v4l2_ext_controls ext;
|
||||
return ext.controls->value;
|
||||
}
|
||||
7
waftools/fragments/vcd_windows.c
Normal file
7
waftools/fragments/vcd_windows.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <windows.h>
|
||||
#include <ntddcdrm.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
19
waftools/fragments/wasapi.c
Normal file
19
waftools/fragments/wasapi.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#define COBJMACROS 1
|
||||
#define _WIN32_WINNT 0x600
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <process.h>
|
||||
#include <initguid.h>
|
||||
#include <audioclient.h>
|
||||
#include <endpointvolume.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <avrt.h>
|
||||
const GUID *check1[] = {
|
||||
&IID_IAudioClient,
|
||||
&IID_IAudioRenderClient,
|
||||
&IID_IAudioClient,
|
||||
&IID_IAudioEndpointVolume,
|
||||
};
|
||||
int main(void) {
|
||||
return 0;
|
||||
}
|
||||
8
waftools/fragments/xf86vm.c
Normal file
8
waftools/fragments/xf86vm.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
XF86VidModeQueryExtension(0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
6
waftools/fragments/xf86xk.c
Normal file
6
waftools/fragments/xf86xk.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <X11/XF86keysym.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return XF86XK_AudioPause;
|
||||
}
|
||||
0
waftools/generators/__init__.py
Normal file
0
waftools/generators/__init__.py
Normal file
36
waftools/generators/headers.py
Normal file
36
waftools/generators/headers.py
Normal file
@@ -0,0 +1,36 @@
|
||||
def __get_version__(ctx):
|
||||
import subprocess
|
||||
process = subprocess.Popen(["sh", "./version.sh", "--print"],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
cwd=ctx.srcnode.abspath())
|
||||
process.wait()
|
||||
(version, err) = process.communicate()
|
||||
return version.strip()
|
||||
|
||||
def __get_build_date__():
|
||||
import time
|
||||
return time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
|
||||
|
||||
def __write_config_h__(ctx):
|
||||
ctx.start_msg("Writing configuration header:")
|
||||
ctx.write_config_header('config.h')
|
||||
ctx.end_msg("config.h", "PINK")
|
||||
|
||||
def __write_version_h__(ctx):
|
||||
ctx.start_msg("Writing header:")
|
||||
ctx.env.VERSION = __get_version__(ctx)
|
||||
ctx.define("VERSION", ctx.env.VERSION)
|
||||
ctx.define("BUILDDATE", __get_build_date__())
|
||||
ctx.write_config_header("version.h")
|
||||
ctx.end_msg("version.h", "PINK")
|
||||
|
||||
def __add_mplayer_defines__(ctx):
|
||||
from sys import argv
|
||||
ctx.define("CONFIGURATION", " ".join(argv))
|
||||
ctx.define("MPLAYER_CONFDIR", ctx.env.CONFDIR)
|
||||
|
||||
def configure(ctx):
|
||||
__add_mplayer_defines__(ctx)
|
||||
__write_config_h__(ctx)
|
||||
__write_version_h__(ctx)
|
||||
37
waftools/generators/sources.py
Normal file
37
waftools/generators/sources.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from waflib.Build import BuildContext
|
||||
import os
|
||||
|
||||
def __file2string_cmd__(ctx):
|
||||
return "${{BIN_PERL}} {0}/TOOLS/file2string.pl ${{SRC}} > ${{TGT}}" \
|
||||
.format(ctx.srcnode.abspath())
|
||||
|
||||
def __matroska_cmd__(ctx, argument):
|
||||
return "${{BIN_PERL}} {0}/TOOLS/matroska.pl {1} ${{SRC}} > ${{TGT}}" \
|
||||
.format(ctx.srcnode.abspath(), argument)
|
||||
|
||||
def __file2string__(ctx, **kwargs):
|
||||
ctx(
|
||||
rule = __file2string_cmd__(ctx),
|
||||
before = ("c",),
|
||||
name = os.path.basename(kwargs['target']),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def __matroska_header__(ctx, **kwargs):
|
||||
ctx(
|
||||
rule = __matroska_cmd__(ctx, '--generate-header'),
|
||||
before = ("c",),
|
||||
name = os.path.basename(kwargs['target']),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def __matroska_definitions__(ctx, **kwargs):
|
||||
ctx(
|
||||
rule = __matroska_cmd__(ctx, '--generate-definitions'),
|
||||
before = ("c",),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
BuildContext.file2string = __file2string__
|
||||
BuildContext.matroska_header = __matroska_header__
|
||||
BuildContext.matroska_definitions = __matroska_definitions__
|
||||
26
waftools/inflectors.py
Normal file
26
waftools/inflectors.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import re
|
||||
|
||||
class DependencyInflector(object):
|
||||
def __init__(self, dependency):
|
||||
self.dep = dependency
|
||||
|
||||
def storage_key(self):
|
||||
return self.__underscore__(self.dep)
|
||||
|
||||
def define_key(self):
|
||||
return ("have_" + self.storage_key()).upper()
|
||||
|
||||
def define_dict(self):
|
||||
return {'define_name': self.define_key()}
|
||||
|
||||
def storage_dict(self):
|
||||
return {'uselib_store': self.storage_key()}
|
||||
|
||||
def __underscore__(self, word):
|
||||
""" Converts a word "into_it_s_underscored_version"
|
||||
Convert any "CamelCased" or "ordinary Word" into an
|
||||
"underscored_word"."""
|
||||
|
||||
return re.sub('[^A-Z^a-z^0-9]+', '_', \
|
||||
re.sub('([a-z\d])([A-Z])', '\\1_\\2', \
|
||||
re.sub('([A-Z]+)([A-Z][a-z])', '\\1_\\2', re.sub('::', '/', word)))).lower()
|
||||
46
waftools/waf_customizations.py
Normal file
46
waftools/waf_customizations.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from waflib.Configure import conf
|
||||
|
||||
@conf
|
||||
def get_config_header(self, defines=True, headers=False, define_prefix=''):
|
||||
"""
|
||||
Only difference is it outputs `#define VAR 0` or `#define VAR value`
|
||||
instead of `#undef VAR` or `#define VAR val`.
|
||||
"""
|
||||
from waflib.Tools.c_config import DEFKEYS, INCKEYS
|
||||
lst = []
|
||||
if headers:
|
||||
for x in self.env[INCKEYS]:
|
||||
lst.append('#include <%s>' % x)
|
||||
|
||||
if defines:
|
||||
for x in self.env[DEFKEYS]:
|
||||
val = self.is_defined(x) and self.get_define(x) or "0"
|
||||
lst.append('#define %s %s' % (define_prefix + x, val))
|
||||
|
||||
return "\n".join(lst)
|
||||
|
||||
from waflib import TaskGen
|
||||
|
||||
@TaskGen.extension('.m')
|
||||
def m_hook(self, node):
|
||||
"""
|
||||
Makes waf call the c compiler for objective-c files
|
||||
"""
|
||||
return self.create_compiled_task('c', node)
|
||||
|
||||
def build(ctx):
|
||||
from waflib import Task
|
||||
cls = Task.classes['cprogram']
|
||||
class cprogram(cls):
|
||||
run_str = cls.hcode + '${LAST_LINKFLAGS}'
|
||||
|
||||
cls = Task.classes['macplist']
|
||||
class macplist(cls):
|
||||
def run(self):
|
||||
from waflib import Utils
|
||||
if getattr(self, 'code', None):
|
||||
txt = self.code
|
||||
else:
|
||||
txt = self.inputs[0].read()
|
||||
txt = Utils.subst_vars(txt, self.env)
|
||||
self.outputs[0].write(txt)
|
||||
Reference in New Issue
Block a user