summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2012-12-11 00:01:56 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-12-11 15:59:42 +0000
commit8ead7dc3cc1b0c878f246ea233e34d58a74a66db (patch)
tree25e3a4d7780837d34f4c90490eb53d3c79006f1b
parentf823f0a0c04d6f13359f0aac4a2946a6e4dd3649 (diff)
downloadpoky-8ead7dc3cc1b0c878f246ea233e34d58a74a66db.tar.gz
bitbake: BBHandler/ast: Simplify/fix EXPORT_FUNCTIONS usage
The current usage of EXPORT_FUNCTIONS is rather problematic since a class list (classes) is passed into the ast statement and cached as it was when first parsed. This class list may be different in other cases but is locked once in the cache. Worse, the construction of classes can be broken by exceptions during parsing at the wrong moments since the state of the parser is not always reset correctly. This can lead to leakage of other classes into the classes list. The current EXPORT_FUNCTIONS implementation looks at the last two currently inherited classes and sets up an indirect function call view the second last class inherited, e.g.: do_configure calls gnomebase_do_configure gnomebase_do_configure calls autotools_do_configure This intermediary doesn't seem to serve a useful purpose. This patch therefore makes builds deterministic and fixes various cache problems and indirection by removing the intermediaries and simply performing directly mapping for the cases where its needed. (Bitbake rev: 9fc98f96f0e0320beda0ce9546275a99336732c1) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/parse/ast.py63
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py15
2 files changed, 32 insertions, 46 deletions
diff --git a/bitbake/lib/bb/parse/ast.py b/bitbake/lib/bb/parse/ast.py
index 4caa93e044..79e9f7e170 100644
--- a/bitbake/lib/bb/parse/ast.py
+++ b/bitbake/lib/bb/parse/ast.py
@@ -179,44 +179,35 @@ class MethodFlagsNode(AstNode):
179 data.delVarFlag(self.key, "fakeroot") 179 data.delVarFlag(self.key, "fakeroot")
180 180
181class ExportFuncsNode(AstNode): 181class ExportFuncsNode(AstNode):
182 def __init__(self, filename, lineno, fns, classes): 182 def __init__(self, filename, lineno, fns, classname):
183 AstNode.__init__(self, filename, lineno) 183 AstNode.__init__(self, filename, lineno)
184 self.n = fns.split() 184 self.n = fns.split()
185 self.classes = classes 185 self.classname = classname
186 186
187 def eval(self, data): 187 def eval(self, data):
188 for f in self.n: 188
189 allvars = [] 189 for func in self.n:
190 allvars.append(f) 190 calledfunc = self.classname + "_" + func
191 allvars.append(self.classes[-1] + "_" + f) 191
192 192 if data.getVar(func) and not data.getVarFlag(func, 'export_func'):
193 vars = [[ allvars[0], allvars[1] ]] 193 continue
194 if len(self.classes) > 1 and self.classes[-2] is not None: 194
195 allvars.append(self.classes[-2] + "_" + f) 195 if data.getVar(func):
196 vars = [] 196 data.setVarFlag(func, 'python', None)
197 vars.append([allvars[2], allvars[1]]) 197 data.setVarFlag(func, 'func', None)
198 vars.append([allvars[0], allvars[2]]) 198
199 199 for flag in [ "func", "python" ]:
200 for (var, calledvar) in vars: 200 if data.getVarFlag(calledfunc, flag):
201 if data.getVar(var) and not data.getVarFlag(var, 'export_func'): 201 data.setVarFlag(func, flag, data.getVarFlag(calledfunc, flag))
202 continue 202 for flag in [ "dirs" ]:
203 203 if data.getVarFlag(func, flag):
204 if data.getVar(var): 204 data.setVarFlag(calledfunc, flag, data.getVarFlag(func, flag))
205 data.setVarFlag(var, 'python', None) 205
206 data.setVarFlag(var, 'func', None) 206 if data.getVarFlag(calledfunc, "python"):
207 207 data.setVar(func, " bb.build.exec_func('" + calledfunc + "', d)\n")
208 for flag in [ "func", "python" ]: 208 else:
209 if data.getVarFlag(calledvar, flag): 209 data.setVar(func, " " + calledfunc + "\n")
210 data.setVarFlag(var, flag, data.getVarFlag(calledvar, flag)) 210 data.setVarFlag(func, 'export_func', '1')
211 for flag in [ "dirs" ]:
212 if data.getVarFlag(var, flag):
213 data.setVarFlag(calledvar, flag, data.getVarFlag(var, flag))
214
215 if data.getVarFlag(calledvar, "python"):
216 data.setVar(var, " bb.build.exec_func('" + calledvar + "', d)\n")
217 else:
218 data.setVar(var, " " + calledvar + "\n")
219 data.setVarFlag(var, 'export_func', '1')
220 211
221class AddTaskNode(AstNode): 212class AddTaskNode(AstNode):
222 def __init__(self, filename, lineno, func, before, after): 213 def __init__(self, filename, lineno, func, before, after):
@@ -288,8 +279,8 @@ def handlePythonMethod(statements, filename, lineno, funcname, modulename, body)
288def handleMethodFlags(statements, filename, lineno, key, m): 279def handleMethodFlags(statements, filename, lineno, key, m):
289 statements.append(MethodFlagsNode(filename, lineno, key, m)) 280 statements.append(MethodFlagsNode(filename, lineno, key, m))
290 281
291def handleExportFuncs(statements, filename, lineno, m, classes): 282def handleExportFuncs(statements, filename, lineno, m, classname):
292 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classes)) 283 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname))
293 284
294def handleAddTask(statements, filename, lineno, m): 285def handleAddTask(statements, filename, lineno, m):
295 func = m.group("func") 286 func = m.group("func")
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index 2e0647b5df..92c55f531a 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -51,7 +51,6 @@ __infunc__ = ""
51__inpython__ = False 51__inpython__ = False
52__body__ = [] 52__body__ = []
53__classname__ = "" 53__classname__ = ""
54classes = [ None, ]
55 54
56cached_statements = {} 55cached_statements = {}
57 56
@@ -107,7 +106,7 @@ def get_statements(filename, absolute_filename, base_name):
107 return statements 106 return statements
108 107
109def handle(fn, d, include): 108def handle(fn, d, include):
110 global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__ 109 global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__, __classname__
111 __body__ = [] 110 __body__ = []
112 __infunc__ = "" 111 __infunc__ = ""
113 __classname__ = "" 112 __classname__ = ""
@@ -125,7 +124,6 @@ def handle(fn, d, include):
125 124
126 if ext == ".bbclass": 125 if ext == ".bbclass":
127 __classname__ = root 126 __classname__ = root
128 classes.append(__classname__)
129 __inherit_cache = d.getVar('__inherit_cache') or [] 127 __inherit_cache = d.getVar('__inherit_cache') or []
130 if not fn in __inherit_cache: 128 if not fn in __inherit_cache:
131 __inherit_cache.append(fn) 129 __inherit_cache.append(fn)
@@ -150,11 +148,8 @@ def handle(fn, d, include):
150 148
151 statements.eval(d) 149 statements.eval(d)
152 150
153 if ext == ".bbclass": 151 if ext != ".bbclass" and include == 0:
154 classes.remove(__classname__) 152 return ast.multi_finalize(fn, d)
155 else:
156 if include == 0:
157 return ast.multi_finalize(fn, d)
158 153
159 if oldfile: 154 if oldfile:
160 d.setVar("FILE", oldfile) 155 d.setVar("FILE", oldfile)
@@ -166,7 +161,7 @@ def handle(fn, d, include):
166 return d 161 return d
167 162
168def feeder(lineno, s, fn, root, statements): 163def feeder(lineno, s, fn, root, statements):
169 global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__, __infunc__, __body__, classes, bb, __residue__ 164 global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__, __infunc__, __body__, bb, __residue__, __classname__
170 if __infunc__: 165 if __infunc__:
171 if s == '}': 166 if s == '}':
172 __body__.append('') 167 __body__.append('')
@@ -225,7 +220,7 @@ def feeder(lineno, s, fn, root, statements):
225 220
226 m = __export_func_regexp__.match(s) 221 m = __export_func_regexp__.match(s)
227 if m: 222 if m:
228 ast.handleExportFuncs(statements, fn, lineno, m, classes) 223 ast.handleExportFuncs(statements, fn, lineno, m, __classname__)
229 return 224 return
230 225
231 m = __addtask_regexp__.match(s) 226 m = __addtask_regexp__.match(s)