1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-30 12:29:55 +00:00

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>
This commit is contained in:
Richard Purdie
2012-12-11 00:01:56 +00:00
parent f823f0a0c0
commit 8ead7dc3cc
2 changed files with 27 additions and 41 deletions
+22 -31
View File
@@ -179,44 +179,35 @@ class MethodFlagsNode(AstNode):
data.delVarFlag(self.key, "fakeroot") data.delVarFlag(self.key, "fakeroot")
class ExportFuncsNode(AstNode): class ExportFuncsNode(AstNode):
def __init__(self, filename, lineno, fns, classes): def __init__(self, filename, lineno, fns, classname):
AstNode.__init__(self, filename, lineno) AstNode.__init__(self, filename, lineno)
self.n = fns.split() self.n = fns.split()
self.classes = classes self.classname = classname
def eval(self, data): def eval(self, data):
for f in self.n:
allvars = []
allvars.append(f)
allvars.append(self.classes[-1] + "_" + f)
vars = [[ allvars[0], allvars[1] ]] for func in self.n:
if len(self.classes) > 1 and self.classes[-2] is not None: calledfunc = self.classname + "_" + func
allvars.append(self.classes[-2] + "_" + f)
vars = []
vars.append([allvars[2], allvars[1]])
vars.append([allvars[0], allvars[2]])
for (var, calledvar) in vars: if data.getVar(func) and not data.getVarFlag(func, 'export_func'):
if data.getVar(var) and not data.getVarFlag(var, 'export_func'): continue
continue
if data.getVar(var): if data.getVar(func):
data.setVarFlag(var, 'python', None) data.setVarFlag(func, 'python', None)
data.setVarFlag(var, 'func', None) data.setVarFlag(func, 'func', None)
for flag in [ "func", "python" ]: for flag in [ "func", "python" ]:
if data.getVarFlag(calledvar, flag): if data.getVarFlag(calledfunc, flag):
data.setVarFlag(var, flag, data.getVarFlag(calledvar, flag)) data.setVarFlag(func, flag, data.getVarFlag(calledfunc, flag))
for flag in [ "dirs" ]: for flag in [ "dirs" ]:
if data.getVarFlag(var, flag): if data.getVarFlag(func, flag):
data.setVarFlag(calledvar, flag, data.getVarFlag(var, flag)) data.setVarFlag(calledfunc, flag, data.getVarFlag(func, flag))
if data.getVarFlag(calledvar, "python"): if data.getVarFlag(calledfunc, "python"):
data.setVar(var, " bb.build.exec_func('" + calledvar + "', d)\n") data.setVar(func, " bb.build.exec_func('" + calledfunc + "', d)\n")
else: else:
data.setVar(var, " " + calledvar + "\n") data.setVar(func, " " + calledfunc + "\n")
data.setVarFlag(var, 'export_func', '1') data.setVarFlag(func, 'export_func', '1')
class AddTaskNode(AstNode): class AddTaskNode(AstNode):
def __init__(self, filename, lineno, func, before, after): def __init__(self, filename, lineno, func, before, after):
@@ -288,8 +279,8 @@ def handlePythonMethod(statements, filename, lineno, funcname, modulename, body)
def handleMethodFlags(statements, filename, lineno, key, m): def handleMethodFlags(statements, filename, lineno, key, m):
statements.append(MethodFlagsNode(filename, lineno, key, m)) statements.append(MethodFlagsNode(filename, lineno, key, m))
def handleExportFuncs(statements, filename, lineno, m, classes): def handleExportFuncs(statements, filename, lineno, m, classname):
statements.append(ExportFuncsNode(filename, lineno, m.group(1), classes)) statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname))
def handleAddTask(statements, filename, lineno, m): def handleAddTask(statements, filename, lineno, m):
func = m.group("func") func = m.group("func")
+5 -10
View File
@@ -51,7 +51,6 @@ __infunc__ = ""
__inpython__ = False __inpython__ = False
__body__ = [] __body__ = []
__classname__ = "" __classname__ = ""
classes = [ None, ]
cached_statements = {} cached_statements = {}
@@ -107,7 +106,7 @@ def get_statements(filename, absolute_filename, base_name):
return statements return statements
def handle(fn, d, include): def handle(fn, d, include):
global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__ global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__, __classname__
__body__ = [] __body__ = []
__infunc__ = "" __infunc__ = ""
__classname__ = "" __classname__ = ""
@@ -125,7 +124,6 @@ def handle(fn, d, include):
if ext == ".bbclass": if ext == ".bbclass":
__classname__ = root __classname__ = root
classes.append(__classname__)
__inherit_cache = d.getVar('__inherit_cache') or [] __inherit_cache = d.getVar('__inherit_cache') or []
if not fn in __inherit_cache: if not fn in __inherit_cache:
__inherit_cache.append(fn) __inherit_cache.append(fn)
@@ -150,11 +148,8 @@ def handle(fn, d, include):
statements.eval(d) statements.eval(d)
if ext == ".bbclass": if ext != ".bbclass" and include == 0:
classes.remove(__classname__) return ast.multi_finalize(fn, d)
else:
if include == 0:
return ast.multi_finalize(fn, d)
if oldfile: if oldfile:
d.setVar("FILE", oldfile) d.setVar("FILE", oldfile)
@@ -166,7 +161,7 @@ def handle(fn, d, include):
return d return d
def feeder(lineno, s, fn, root, statements): def feeder(lineno, s, fn, root, statements):
global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__, __infunc__, __body__, classes, bb, __residue__ global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__, __infunc__, __body__, bb, __residue__, __classname__
if __infunc__: if __infunc__:
if s == '}': if s == '}':
__body__.append('') __body__.append('')
@@ -225,7 +220,7 @@ def feeder(lineno, s, fn, root, statements):
m = __export_func_regexp__.match(s) m = __export_func_regexp__.match(s)
if m: if m:
ast.handleExportFuncs(statements, fn, lineno, m, classes) ast.handleExportFuncs(statements, fn, lineno, m, __classname__)
return return
m = __addtask_regexp__.match(s) m = __addtask_regexp__.match(s)