summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/codeparser.py
diff options
context:
space:
mode:
authorChristopher Larson <kergoth@gmail.com>2014-04-28 08:27:34 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-04-29 17:34:24 +0100
commit107269d9d02debe1adde9745df52da9dd5faf5c7 (patch)
treeaa28100b43a33676380c0dd9fea7b340e7c509f5 /bitbake/lib/bb/codeparser.py
parent3d34b49f4a4e2bc05ade5503d845d92f4051be43 (diff)
downloadpoky-107269d9d02debe1adde9745df52da9dd5faf5c7.tar.gz
bitbake: codeparser: don't interact with the cache for subshells
Doing so was causing leakage between the execs of the main value and that of the subshell value, and was causing the cached subshell value to be used for the overall variable. At the least this could cause execs contamination between two variables that while differing, run the same subshell. Beyond that, it's possible we could have been using an incomplete cached value of a subshell for that of the main value. Before this, bb_codeparser.dat would change between parses with differing bbfile parse order. After, it does not change. The codeparser cache version is bumped, to ensure we don't use potentially incorrect cached values from previous runs. This should hopefully resolve the difficult-to-reproduce issues we've seen at Mentor Graphics where bitbake emits a script to run a task and misses dependent functions, resulting in 'command not found' failures. This issue has also been mentioned on the oe devel list, where someone hit a case where oe_runmake was missing from a do_install task (IIRC). Adding debug information showed that bitbake's information about the variable dependencies for this task is inaccurate in the failure cases. (Bitbake rev: 97537e4786a1e3a329249497498b59b8f5174fc3) Signed-off-by: Christopher Larson <kergoth@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/codeparser.py')
-rw-r--r--bitbake/lib/bb/codeparser.py21
1 files changed, 12 insertions, 9 deletions
diff --git a/bitbake/lib/bb/codeparser.py b/bitbake/lib/bb/codeparser.py
index a50b9f268a..de8d2eb08d 100644
--- a/bitbake/lib/bb/codeparser.py
+++ b/bitbake/lib/bb/codeparser.py
@@ -35,7 +35,7 @@ def check_indent(codestr):
35 35
36class CodeParserCache(MultiProcessCache): 36class CodeParserCache(MultiProcessCache):
37 cache_file_name = "bb_codeparser.dat" 37 cache_file_name = "bb_codeparser.dat"
38 CACHE_VERSION = 4 38 CACHE_VERSION = 5
39 39
40 def __init__(self): 40 def __init__(self):
41 MultiProcessCache.__init__(self) 41 MultiProcessCache.__init__(self)
@@ -217,6 +217,15 @@ class ShellParser():
217 self.execs = codeparsercache.shellcacheextras[h]["execs"] 217 self.execs = codeparsercache.shellcacheextras[h]["execs"]
218 return self.execs 218 return self.execs
219 219
220 self._parse_shell(value)
221 self.execs = set(cmd for cmd in self.allexecs if cmd not in self.funcdefs)
222
223 codeparsercache.shellcacheextras[h] = {}
224 codeparsercache.shellcacheextras[h]["execs"] = self.execs
225
226 return self.execs
227
228 def _parse_shell(self, value):
220 try: 229 try:
221 tokens, _ = pyshyacc.parse(value, eof=True, debug=False) 230 tokens, _ = pyshyacc.parse(value, eof=True, debug=False)
222 except pyshlex.NeedMore: 231 except pyshlex.NeedMore:
@@ -224,12 +233,6 @@ class ShellParser():
224 233
225 for token in tokens: 234 for token in tokens:
226 self.process_tokens(token) 235 self.process_tokens(token)
227 self.execs = set(cmd for cmd in self.allexecs if cmd not in self.funcdefs)
228
229 codeparsercache.shellcacheextras[h] = {}
230 codeparsercache.shellcacheextras[h]["execs"] = self.execs
231
232 return self.execs
233 236
234 def process_tokens(self, tokens): 237 def process_tokens(self, tokens):
235 """Process a supplied portion of the syntax tree as returned by 238 """Process a supplied portion of the syntax tree as returned by
@@ -303,7 +306,7 @@ class ShellParser():
303 306
304 if part[0] in ('`', '$('): 307 if part[0] in ('`', '$('):
305 command = pyshlex.wordtree_as_string(part[1:-1]) 308 command = pyshlex.wordtree_as_string(part[1:-1])
306 self.parse_shell(command) 309 self._parse_shell(command)
307 310
308 if word[0] in ("cmd_name", "cmd_word"): 311 if word[0] in ("cmd_name", "cmd_word"):
309 if word in words: 312 if word in words:
@@ -322,7 +325,7 @@ class ShellParser():
322 self.log.debug(1, self.unhandled_template % cmd) 325 self.log.debug(1, self.unhandled_template % cmd)
323 elif cmd == "eval": 326 elif cmd == "eval":
324 command = " ".join(word for _, word in words[1:]) 327 command = " ".join(word for _, word in words[1:])
325 self.parse_shell(command) 328 self._parse_shell(command)
326 else: 329 else:
327 self.allexecs.add(cmd) 330 self.allexecs.add(cmd)
328 break 331 break