diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-11-25 22:59:39 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-11-26 23:01:33 +0000 |
commit | a10301f6a90567c2d2eca9306a4b7b752f58a9c2 (patch) | |
tree | 41da459bd5e16ee0d8e9d502532b34c284e0fdd9 /bitbake | |
parent | d0616923724c5d021a816ec778e836283a2ccfe2 (diff) | |
download | poky-a10301f6a90567c2d2eca9306a4b7b752f58a9c2.tar.gz |
bitbake: data/codeparser: Improve handling of contains functions
One of the current frustrations with the sstate checksums is that
code like base_contains('X', 'y',...) adds a full dependency on X
and varies depend even on whitespace changes in X.
This patch adds special handling of the contains functions to expand
the first parameter and check for the flag specified by the second
parameter (assuming its a string).
The result is then appended to the value of the variable with a "Set"
or "Unset" status. If the flag is added/removed, the stored variable
value changes and hence the checksum changes. No dependency on X
is added so it is free to change with regard to other flags or
whitespace.
This code is far from ideal, ideally we'd have properly typed variables
however it fixes a major annoyance of the current checksums and
is of enough value its worth adding in a stopgap solution. It shouldn't
significantly restrict any propely typed variable implementation in
future.
(Bitbake rev: ed2d0a22a80299de0cfd377999950cf4b26c512e)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Christopher Larson <chris_larson@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/codeparser.py | 14 | ||||
-rw-r--r-- | bitbake/lib/bb/data.py | 18 | ||||
-rw-r--r-- | bitbake/lib/bb/data_smart.py | 4 |
3 files changed, 33 insertions, 3 deletions
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 @@ | |||
1 | import ast | 1 | import ast |
2 | import codegen | 2 | import codegen |
3 | import logging | 3 | import logging |
4 | import collections | ||
4 | import os.path | 5 | import os.path |
5 | import bb.utils, bb.data | 6 | import bb.utils, bb.data |
6 | from itertools import chain | 7 | from itertools import chain |
@@ -35,7 +36,7 @@ def check_indent(codestr): | |||
35 | 36 | ||
36 | class CodeParserCache(MultiProcessCache): | 37 | class CodeParserCache(MultiProcessCache): |
37 | cache_file_name = "bb_codeparser.dat" | 38 | cache_file_name = "bb_codeparser.dat" |
38 | CACHE_VERSION = 3 | 39 | CACHE_VERSION = 4 |
39 | 40 | ||
40 | def __init__(self): | 41 | def __init__(self): |
41 | MultiProcessCache.__init__(self) | 42 | MultiProcessCache.__init__(self) |
@@ -122,7 +123,11 @@ class PythonParser(): | |||
122 | name = self.called_node_name(node.func) | 123 | name = self.called_node_name(node.func) |
123 | if name in self.getvars or name in self.containsfuncs: | 124 | if name in self.getvars or name in self.containsfuncs: |
124 | if isinstance(node.args[0], ast.Str): | 125 | if isinstance(node.args[0], ast.Str): |
125 | self.references.add(node.args[0].s) | 126 | varname = node.args[0].s |
127 | if name in self.containsfuncs and isinstance(node.args[1], ast.Str): | ||
128 | self.contains[varname].add(node.args[1].s) | ||
129 | else: | ||
130 | self.references.add(node.args[0].s) | ||
126 | else: | 131 | else: |
127 | self.warn(node.func, node.args[0]) | 132 | self.warn(node.func, node.args[0]) |
128 | elif name in self.execfuncs: | 133 | elif name in self.execfuncs: |
@@ -148,6 +153,7 @@ class PythonParser(): | |||
148 | 153 | ||
149 | def __init__(self, name, log): | 154 | def __init__(self, name, log): |
150 | self.var_execs = set() | 155 | self.var_execs = set() |
156 | self.contains = collections.defaultdict(set) | ||
151 | self.execs = set() | 157 | self.execs = set() |
152 | self.references = set() | 158 | self.references = set() |
153 | self.log = BufferedLogger('BitBake.Data.%s' % name, logging.DEBUG, log) | 159 | self.log = BufferedLogger('BitBake.Data.%s' % name, logging.DEBUG, log) |
@@ -161,14 +167,15 @@ class PythonParser(): | |||
161 | if h in codeparsercache.pythoncache: | 167 | if h in codeparsercache.pythoncache: |
162 | self.references = codeparsercache.pythoncache[h]["refs"] | 168 | self.references = codeparsercache.pythoncache[h]["refs"] |
163 | self.execs = codeparsercache.pythoncache[h]["execs"] | 169 | self.execs = codeparsercache.pythoncache[h]["execs"] |
170 | self.contains = codeparsercache.pythoncache[h]["contains"] | ||
164 | return | 171 | return |
165 | 172 | ||
166 | if h in codeparsercache.pythoncacheextras: | 173 | if h in codeparsercache.pythoncacheextras: |
167 | self.references = codeparsercache.pythoncacheextras[h]["refs"] | 174 | self.references = codeparsercache.pythoncacheextras[h]["refs"] |
168 | self.execs = codeparsercache.pythoncacheextras[h]["execs"] | 175 | self.execs = codeparsercache.pythoncacheextras[h]["execs"] |
176 | self.contains = codeparsercache.pythoncacheextras[h]["contains"] | ||
169 | return | 177 | return |
170 | 178 | ||
171 | |||
172 | code = compile(check_indent(str(node)), "<string>", "exec", | 179 | code = compile(check_indent(str(node)), "<string>", "exec", |
173 | ast.PyCF_ONLY_AST) | 180 | ast.PyCF_ONLY_AST) |
174 | 181 | ||
@@ -181,6 +188,7 @@ class PythonParser(): | |||
181 | codeparsercache.pythoncacheextras[h] = {} | 188 | codeparsercache.pythoncacheextras[h] = {} |
182 | codeparsercache.pythoncacheextras[h]["refs"] = self.references | 189 | codeparsercache.pythoncacheextras[h]["refs"] = self.references |
183 | codeparsercache.pythoncacheextras[h]["execs"] = self.execs | 190 | codeparsercache.pythoncacheextras[h]["execs"] = self.execs |
191 | codeparsercache.pythoncacheextras[h]["contains"] = self.contains | ||
184 | 192 | ||
185 | class ShellParser(): | 193 | class ShellParser(): |
186 | def __init__(self, name, log): | 194 | 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): | |||
299 | vardeps = varflags.get("vardeps") | 299 | vardeps = varflags.get("vardeps") |
300 | value = d.getVar(key, False) | 300 | value = d.getVar(key, False) |
301 | 301 | ||
302 | def handle_contains(value, contains, d): | ||
303 | newvalue = "" | ||
304 | for k in contains: | ||
305 | l = (d.getVar(k, True) or "").split() | ||
306 | for word in contains[k]: | ||
307 | if word in l: | ||
308 | newvalue += "\n%s{%s} = Set" % (k, word) | ||
309 | else: | ||
310 | newvalue += "\n%s{%s} = Unset" % (k, word) | ||
311 | if not newvalue: | ||
312 | return value | ||
313 | if not value: | ||
314 | return newvalue | ||
315 | return value + newvalue | ||
316 | |||
302 | if "vardepvalue" in varflags: | 317 | if "vardepvalue" in varflags: |
303 | value = varflags.get("vardepvalue") | 318 | value = varflags.get("vardepvalue") |
304 | elif varflags.get("func"): | 319 | elif varflags.get("func"): |
@@ -309,6 +324,7 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d): | |||
309 | logger.warn("Variable %s contains tabs, please remove these (%s)" % (key, d.getVar("FILE", True))) | 324 | logger.warn("Variable %s contains tabs, please remove these (%s)" % (key, d.getVar("FILE", True))) |
310 | parser.parse_python(parsedvar.value) | 325 | parser.parse_python(parsedvar.value) |
311 | deps = deps | parser.references | 326 | deps = deps | parser.references |
327 | value = handle_contains(value, parser.contains, d) | ||
312 | else: | 328 | else: |
313 | parsedvar = d.expandWithRefs(value, key) | 329 | parsedvar = d.expandWithRefs(value, key) |
314 | parser = bb.codeparser.ShellParser(key, logger) | 330 | parser = bb.codeparser.ShellParser(key, logger) |
@@ -318,10 +334,12 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d): | |||
318 | parser.log.flush() | 334 | parser.log.flush() |
319 | deps = deps | parsedvar.references | 335 | deps = deps | parsedvar.references |
320 | deps = deps | (keys & parser.execs) | (keys & parsedvar.execs) | 336 | deps = deps | (keys & parser.execs) | (keys & parsedvar.execs) |
337 | value = handle_contains(value, parsedvar.contains, d) | ||
321 | else: | 338 | else: |
322 | parser = d.expandWithRefs(value, key) | 339 | parser = d.expandWithRefs(value, key) |
323 | deps |= parser.references | 340 | deps |= parser.references |
324 | deps = deps | (keys & parser.execs) | 341 | deps = deps | (keys & parser.execs) |
342 | value = handle_contains(value, parser.contains, d) | ||
325 | 343 | ||
326 | # Add varflags, assuming an exclusion list is set | 344 | # Add varflags, assuming an exclusion list is set |
327 | if varflagsexcl: | 345 | 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 | |||
35 | import bb, bb.codeparser | 35 | import bb, bb.codeparser |
36 | from bb import utils | 36 | from bb import utils |
37 | from bb.COW import COWDictBase | 37 | from bb.COW import COWDictBase |
38 | import collections | ||
38 | 39 | ||
39 | logger = logging.getLogger("BitBake.Data") | 40 | logger = logging.getLogger("BitBake.Data") |
40 | 41 | ||
@@ -88,6 +89,7 @@ class VariableParse: | |||
88 | 89 | ||
89 | self.references = set() | 90 | self.references = set() |
90 | self.execs = set() | 91 | self.execs = set() |
92 | self.contains = collections.defaultdict(set) | ||
91 | 93 | ||
92 | def var_sub(self, match): | 94 | def var_sub(self, match): |
93 | key = match.group()[2:-1] | 95 | key = match.group()[2:-1] |
@@ -120,6 +122,8 @@ class VariableParse: | |||
120 | self.references |= parser.references | 122 | self.references |= parser.references |
121 | self.execs |= parser.execs | 123 | self.execs |= parser.execs |
122 | 124 | ||
125 | for k in parser.contains: | ||
126 | self.contains[k].update(parser.contains[k]) | ||
123 | value = utils.better_eval(codeobj, DataContext(self.d)) | 127 | value = utils.better_eval(codeobj, DataContext(self.d)) |
124 | return str(value) | 128 | return str(value) |
125 | 129 | ||