diff --git a/bitbake/lib/bb/codeparser.py b/bitbake/lib/bb/codeparser.py index 116481559a..6e34eff999 100644 --- a/bitbake/lib/bb/codeparser.py +++ b/bitbake/lib/bb/codeparser.py @@ -1,6 +1,7 @@ import ast import codegen import logging +import collections import os.path import bb.utils, bb.data from itertools import chain @@ -35,7 +36,7 @@ def check_indent(codestr): class CodeParserCache(MultiProcessCache): cache_file_name = "bb_codeparser.dat" - CACHE_VERSION = 3 + CACHE_VERSION = 4 def __init__(self): MultiProcessCache.__init__(self) @@ -122,7 +123,11 @@ class PythonParser(): name = self.called_node_name(node.func) if name in self.getvars or name in self.containsfuncs: if isinstance(node.args[0], ast.Str): - self.references.add(node.args[0].s) + varname = node.args[0].s + if name in self.containsfuncs and isinstance(node.args[1], ast.Str): + self.contains[varname].add(node.args[1].s) + else: + self.references.add(node.args[0].s) else: self.warn(node.func, node.args[0]) elif name in self.execfuncs: @@ -148,6 +153,7 @@ class PythonParser(): def __init__(self, name, log): self.var_execs = set() + self.contains = collections.defaultdict(set) self.execs = set() self.references = set() self.log = BufferedLogger('BitBake.Data.%s' % name, logging.DEBUG, log) @@ -161,14 +167,15 @@ class PythonParser(): if h in codeparsercache.pythoncache: self.references = codeparsercache.pythoncache[h]["refs"] self.execs = codeparsercache.pythoncache[h]["execs"] + self.contains = codeparsercache.pythoncache[h]["contains"] return if h in codeparsercache.pythoncacheextras: self.references = codeparsercache.pythoncacheextras[h]["refs"] self.execs = codeparsercache.pythoncacheextras[h]["execs"] + self.contains = codeparsercache.pythoncacheextras[h]["contains"] return - code = compile(check_indent(str(node)), "", "exec", ast.PyCF_ONLY_AST) @@ -181,6 +188,7 @@ class PythonParser(): codeparsercache.pythoncacheextras[h] = {} codeparsercache.pythoncacheextras[h]["refs"] = self.references codeparsercache.pythoncacheextras[h]["execs"] = self.execs + codeparsercache.pythoncacheextras[h]["contains"] = self.contains class ShellParser(): def __init__(self, name, log): diff --git a/bitbake/lib/bb/data.py b/bitbake/lib/bb/data.py index bdd1e79e24..3d2c6a4975 100644 --- a/bitbake/lib/bb/data.py +++ b/bitbake/lib/bb/data.py @@ -299,6 +299,21 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d): vardeps = varflags.get("vardeps") value = d.getVar(key, False) + def handle_contains(value, contains, d): + newvalue = "" + for k in contains: + l = (d.getVar(k, True) or "").split() + for word in contains[k]: + if word in l: + newvalue += "\n%s{%s} = Set" % (k, word) + else: + newvalue += "\n%s{%s} = Unset" % (k, word) + if not newvalue: + return value + if not value: + return newvalue + return value + newvalue + if "vardepvalue" in varflags: value = varflags.get("vardepvalue") elif varflags.get("func"): @@ -309,6 +324,7 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d): logger.warn("Variable %s contains tabs, please remove these (%s)" % (key, d.getVar("FILE", True))) parser.parse_python(parsedvar.value) deps = deps | parser.references + value = handle_contains(value, parser.contains, d) else: parsedvar = d.expandWithRefs(value, key) parser = bb.codeparser.ShellParser(key, logger) @@ -318,10 +334,12 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d): parser.log.flush() deps = deps | parsedvar.references deps = deps | (keys & parser.execs) | (keys & parsedvar.execs) + value = handle_contains(value, parsedvar.contains, d) else: parser = d.expandWithRefs(value, key) deps |= parser.references deps = deps | (keys & parser.execs) + value = handle_contains(value, parser.contains, d) # Add varflags, assuming an exclusion list is set if varflagsexcl: diff --git a/bitbake/lib/bb/data_smart.py b/bitbake/lib/bb/data_smart.py index a1cbaba62b..9a6f767116 100644 --- a/bitbake/lib/bb/data_smart.py +++ b/bitbake/lib/bb/data_smart.py @@ -35,6 +35,7 @@ import hashlib import bb, bb.codeparser from bb import utils from bb.COW import COWDictBase +import collections logger = logging.getLogger("BitBake.Data") @@ -88,6 +89,7 @@ class VariableParse: self.references = set() self.execs = set() + self.contains = collections.defaultdict(set) def var_sub(self, match): key = match.group()[2:-1] @@ -120,6 +122,8 @@ class VariableParse: self.references |= parser.references self.execs |= parser.execs + for k in parser.contains: + self.contains[k].update(parser.contains[k]) value = utils.better_eval(codeobj, DataContext(self.d)) return str(value)