summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2017-10-15 09:48:48 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2017-10-15 09:48:48 +0200
commit4892bb7691059c038d150545dfe69e1483ec36cc (patch)
tree8c2a47c6b8568a88ce614453737fd6bfaa9342c9
parentb4c1f0aae372df61ace6e179faba75746dff74a5 (diff)
downloadmpv-4892bb7691059c038d150545dfe69e1483ec36cc.tar.bz2
mpv-4892bb7691059c038d150545dfe69e1483ec36cc.tar.xz
tmp
-rw-r--r--waftools/dependencies.py454
-rw-r--r--waftools/deps_parser.py15
-rw-r--r--waftools/detections/compiler.py10
-rw-r--r--waftools/generators/headers.py2
-rw-r--r--wscript15
5 files changed, 273 insertions, 223 deletions
diff --git a/waftools/dependencies.py b/waftools/dependencies.py
index 3cef6a3562..9330b556eb 100644
--- a/waftools/dependencies.py
+++ b/waftools/dependencies.py
@@ -1,224 +1,260 @@
-from waflib.Errors import ConfigurationError, WafError
+import pprint
from waflib.Configure import conf
-from waflib.Build import BuildContext
-from waflib.Logs import pprint
import deps_parser
-import inflector
-class DependencyError(Exception):
- pass
+pp = pprint.PrettyPrinter().pprint
-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)
+def test_build(ctx):
+ ctx(rule='echo hello', shell=True, always=True)
- known_deps.add(self.identifier)
-
- if 'deps' in self.attributes:
- self.ctx.ensure_dependency_is_known(self.attributes['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_group_disabled()
- self.check_disabled()
- self.check_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`.
- self.ctx.undefine(inflector.define_key(self.identifier))
- self.fatal_if_needed()
- return
-
- self.check_autodetect_func()
-
- def check_group_disabled(self):
- if 'groups' in self.attributes:
- groups = self.attributes['groups']
- disabled = (self.enabled_option(g) == False for g in groups)
- if any(disabled):
- self.skip()
- raise DependencyError
-
- 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_dependencies(self):
- if 'deps' in self.attributes:
- ok, why = deps_parser.check_dependency_expr(self.attributes['deps'],
- self.satisfied_deps)
- if not ok:
- self.skip(why)
- raise DependencyError
-
- def check_autodetect_func(self):
- if self.attributes['func'](self.ctx, self.identifier):
- self.success(self.identifier)
- else:
- self.fail()
- self.ctx.undefine(inflector.define_key(self.identifier))
- self.fatal_if_needed()
-
- def enabled_option(self, identifier=None):
- try:
- return getattr(self.ctx.options, self.enabled_option_repr(identifier))
- except AttributeError:
- pass
- return None
-
- def enabled_option_repr(self, identifier):
- return "enable_{0}".format(identifier or 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.get('fmsg', 'Unsatisfied requirement'))
-
- 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
+@conf
+def parse_dependencies(ctx, checks):
+ def valid_symbol(check_name):
+ return not check_name.startswith('os-')
-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.known_deps.add(target)
- ctx.satisfied_deps.add(target)
+ def multicheck_dict(check):
+ # our checks take ctx, dependency_id, we need to curry the
+ # dependency_id in and just accept ctx as argument
+ def curry_id(fn):
+ def curried(ctx):
+ return fn(ctx, check['name'])
+ return curried
- ctx.deps_msg = {}
- ctx.known_deps = set()
- ctx.satisfied_deps = set()
- __detect_target_os_dependency__(ctx)
+ result = {
+ 'id': check['name'],
+ 'msg': 'Checking for ' + check['desc'],
+ 'func': curry_id(check['func']),
+ }
-@conf
-def ensure_dependency_is_known(ctx, depnames):
- def check(ast):
- if isinstance(ast, deps_parser.AstSym):
- if (not ast.name.startswith('os-')) and ast.name not in ctx.known_deps:
- raise ConfigurationError(
- "error in dependencies definition: dependency {0} in"
- " {1} is unknown.".format(ast.name, depnames))
- elif isinstance(ast, deps_parser.AstOp):
- for sub in ast.sub:
- check(sub)
- else:
- assert False
- check(deps_parser.parse_expr(depnames))
+ if ('deps' in check):
+ after_tests = deps_parser.symbols_list(check['deps'])
+ result['after_tests'] = filter(valid_symbol, after_tests)
-@conf
-def mark_satisfied(ctx, dependency_identifier):
- ctx.satisfied_deps.add(dependency_identifier)
+ return result
-@conf
-def add_optional_message(ctx, dependency_identifier, message):
- ctx.deps_msg[dependency_identifier] = message
+ known_deps = set()
+ satisfied_deps = set()
-@conf
-def parse_dependencies(ctx, dependencies):
- def __check_dependency__(ctx, dependency):
- Dependency(ctx,
- ctx.known_deps,
- ctx.satisfied_deps,
- dependency).check()
+ rules = map(multicheck_dict, checks)
+ ctx.multicheck(*rules)
- [__check_dependency__(ctx, dependency) for dependency in dependencies]
+ ctx.env.known_deps = list(known_deps)
+ ctx.env.satisfied_deps = list(satisfied_deps)
@conf
def dependency_satisfied(ctx, dependency_identifier):
- ctx.ensure_dependency_is_known(dependency_identifier)
- ok, _ = deps_parser.check_dependency_expr(dependency_identifier,
- ctx.satisfied_deps)
- return ok
-
-@conf
-def store_dependencies_lists(ctx):
- ctx.env.known_deps = list(ctx.known_deps)
- ctx.env.satisfied_deps = list(ctx.satisfied_deps)
-
-@conf
-def unpack_dependencies_lists(ctx):
- ctx.known_deps = set(ctx.env.known_deps)
- ctx.satisfied_deps = set(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):
- return dependency_satisfied(ctx, dependency)
-
- 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)]
-
-"""
-Like filtered_sources(), but pick only the first entry that matches, and
-return its filename.
-"""
-def pick_first_matching_dep(ctx, deps):
- files = filtered_sources(ctx, deps)
- if len(files) > 0:
- return files[0]
- else:
- raise DependencyError
-
-def env_fetch(tx):
- def fn(ctx):
- deps = 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 [inflector.storage_key(dep) for dep in ctx.env.satisfied_deps]
-
-BuildContext.filtered_sources = filtered_sources
-BuildContext.pick_first_matching_dep = pick_first_matching_dep
-BuildContext.dependencies_use = dependencies_use
-BuildContext.dependencies_includes = env_fetch(lambda x: "INCLUDES_{0}".format(x))
-BuildContext.dependency_satisfied = dependency_satisfied
+ return False
+
+# from waflib.Errors import ConfigurationError, WafError
+# from waflib.Configure import conf
+# from waflib.Build import BuildContext
+# from waflib.Logs import pprint
+# import inflector
+#
+# 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)
+#
+# known_deps.add(self.identifier)
+#
+# if 'deps' in self.attributes:
+# self.ctx.ensure_dependency_is_known(self.attributes['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_group_disabled()
+# self.check_disabled()
+# self.check_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`.
+# self.ctx.undefine(inflector.define_key(self.identifier))
+# self.fatal_if_needed()
+# return
+#
+# self.check_autodetect_func()
+#
+# def check_group_disabled(self):
+# if 'groups' in self.attributes:
+# groups = self.attributes['groups']
+# disabled = (self.enabled_option(g) == False for g in groups)
+# if any(disabled):
+# self.skip()
+# raise DependencyError
+#
+# 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_dependencies(self):
+# if 'deps' in self.attributes:
+# ok, why = deps_parser.check_dependency_expr(self.attributes['deps'],
+# self.satisfied_deps)
+# if not ok:
+# self.skip(why)
+# raise DependencyError
+#
+# def check_autodetect_func(self):
+# if self.attributes['func'](self.ctx, self.identifier):
+# self.success(self.identifier)
+# else:
+# self.fail()
+# self.ctx.undefine(inflector.define_key(self.identifier))
+# self.fatal_if_needed()
+#
+# def enabled_option(self, identifier=None):
+# try:
+# return getattr(self.ctx.options, self.enabled_option_repr(identifier))
+# except AttributeError:
+# pass
+# return None
+#
+# def enabled_option_repr(self, identifier):
+# return "enable_{0}".format(identifier or 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.get('fmsg', 'Unsatisfied requirement'))
+#
+# 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.known_deps.add(target)
+# ctx.satisfied_deps.add(target)
+#
+# ctx.deps_msg = {}
+# ctx.known_deps = set()
+# ctx.satisfied_deps = set()
+# __detect_target_os_dependency__(ctx)
+#
+# @conf
+# def ensure_dependency_is_known(ctx, depnames):
+# def check(ast):
+# if isinstance(ast, deps_parser.AstSym):
+# if (not ast.name.startswith('os-')) and ast.name not in ctx.known_deps:
+# raise ConfigurationError(
+# "error in dependencies definition: dependency {0} in"
+# " {1} is unknown.".format(ast.name, depnames))
+# elif isinstance(ast, deps_parser.AstOp):
+# for sub in ast.sub:
+# check(sub)
+# else:
+# assert False
+# check(deps_parser.parse_expr(depnames))
+#
+# @conf
+# def mark_satisfied(ctx, dependency_identifier):
+# ctx.satisfied_deps.add(dependency_identifier)
+#
+# @conf
+# def add_optional_message(ctx, dependency_identifier, message):
+# ctx.deps_msg[dependency_identifier] = message
+#
+# @conf
+# def dependency_satisfied(ctx, dependency_identifier):
+# ctx.ensure_dependency_is_known(dependency_identifier)
+# ok, _ = deps_parser.check_dependency_expr(dependency_identifier,
+# ctx.satisfied_deps)
+# return ok
+#
+# @conf
+# def store_dependencies_lists(ctx):
+# ctx.env.known_deps = list(ctx.known_deps)
+# ctx.env.satisfied_deps = list(ctx.satisfied_deps)
+#
+# @conf
+# def unpack_dependencies_lists(ctx):
+# ctx.known_deps = set(ctx.env.known_deps)
+# ctx.satisfied_deps = set(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):
+# return dependency_satisfied(ctx, dependency)
+#
+# 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)]
+#
+# """
+# Like filtered_sources(), but pick only the first entry that matches, and
+# return its filename.
+# """
+# def pick_first_matching_dep(ctx, deps):
+# files = filtered_sources(ctx, deps)
+# if len(files) > 0:
+# return files[0]
+# else:
+# raise DependencyError
+#
+# def env_fetch(tx):
+# def fn(ctx):
+# deps = 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 [inflector.storage_key(dep) for dep in ctx.env.satisfied_deps]
+#
+# BuildContext.filtered_sources = filtered_sources
+# BuildContext.pick_first_matching_dep = pick_first_matching_dep
+# 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/deps_parser.py b/waftools/deps_parser.py
index eef3b6f9e8..e98a2461b2 100644
--- a/waftools/deps_parser.py
+++ b/waftools/deps_parser.py
@@ -1,3 +1,4 @@
+import itertools
class ParseError(Exception):
pass
@@ -143,6 +144,20 @@ def convert_dnf(ast):
return redist(flatten(simplify_negation(ast)))
+# returns all the AstSym names
+def symbols_list(expr):
+ def flatten(lst):
+ return list(itertools.chain.from_iterable(lst))
+
+ ast = parse_expr(expr)
+ def eval_ast(ast):
+ if isinstance(ast, AstSym):
+ return [ast.name]
+ elif isinstance(ast, AstOp):
+ return flatten([eval_ast(x) for x in ast.sub])
+ assert False
+ return eval_ast(ast)
+
# Returns (success_as_bool, failure_reason_as_string)
def check_dependency_expr(expr, deps):
ast = parse_expr(expr)
diff --git a/waftools/detections/compiler.py b/waftools/detections/compiler.py
index 7033cf561f..834d72aa3e 100644
--- a/waftools/detections/compiler.py
+++ b/waftools/detections/compiler.py
@@ -12,8 +12,14 @@ def __get_cc_env_vars__(cc):
return ""
def __test_and_add_flags__(ctx, flags):
- for flag in flags:
- ctx.check_cc(cflags=flag, uselib_store="compiler", mandatory=False)
+ def _mapf(flag):
+ return {
+ 'cflags': flag,
+ 'uselib_store': 'compiler',
+ 'mandatory': False,
+ 'msg': 'Checking for compiler header ' + flag,
+ }
+ ctx.multicheck(*map(_mapf, flags), msg = 'Checking for compiler headers...')
ctx.env.CFLAGS += ctx.env.CFLAGS_compiler
def __add_generic_flags__(ctx):
diff --git a/waftools/generators/headers.py b/waftools/generators/headers.py
index 84f914c2c1..cf9b7ebc6e 100644
--- a/waftools/generators/headers.py
+++ b/waftools/generators/headers.py
@@ -17,7 +17,7 @@ def __escape_c_string(s):
def __get_features_string__(ctx):
import inflector
stuff = []
- for dependency_identifier in ctx.satisfied_deps:
+ for dependency_identifier in ctx.env.satisfied_deps:
defkey = inflector.define_key(dependency_identifier)
if ctx.is_defined(defkey) and ctx.get_define(defkey) == "1":
stuff.append(dependency_identifier)
diff --git a/wscript b/wscript
index b50d278d41..b97d3742e9 100644
--- a/wscript
+++ b/wscript
@@ -1053,18 +1053,13 @@ def configure(ctx):
while re.match('\$\{([^}]+)\}', ctx.env[varname]):
ctx.env[varname] = Utils.subst_vars(ctx.env[varname], ctx.env)
- ctx.parse_dependencies(build_options)
- ctx.parse_dependencies(main_dependencies)
- ctx.parse_dependencies(audio_output_features)
- ctx.parse_dependencies(video_output_features)
- ctx.parse_dependencies(libav_dependencies)
- ctx.parse_dependencies(hwaccel_features)
- ctx.parse_dependencies(radio_and_tv_features)
-
if ctx.options.LUA_VER:
ctx.options.enable_lua = True
- ctx.parse_dependencies(standalone_features)
+ ctx.parse_dependencies(
+ build_options + main_dependencies + audio_output_features +
+ video_output_features + libav_dependencies + hwaccel_features +
+ radio_and_tv_features + standalone_features)
ctx.load('generators.headers')
@@ -1081,8 +1076,6 @@ def configure(ctx):
# of exported symbols via mpv.def.
ctx.env.LINKFLAGS += ['-rdynamic']
- ctx.store_dependencies_lists()
-
def __write_version__(ctx):
ctx.env.VERSIONH_ST = '--versionh="%s"'
ctx.env.CWD_ST = '--cwd="%s"'