diff --git a/bitbake/lib/bb/parse/ast.py b/bitbake/lib/bb/parse/ast.py index d30b688965..7581d003fd 100644 --- a/bitbake/lib/bb/parse/ast.py +++ b/bitbake/lib/bb/parse/ast.py @@ -314,6 +314,16 @@ class InheritNode(AstNode): def eval(self, data): bb.parse.BBHandler.inherit(self.classes, self.filename, self.lineno, data) +class InheritDeferredNode(AstNode): + def __init__(self, filename, lineno, classes): + AstNode.__init__(self, filename, lineno) + self.inherit = (classes, filename, lineno) + + def eval(self, data): + inherits = data.getVar('__BBDEFINHERITS', False) or [] + inherits.append(self.inherit) + data.setVar('__BBDEFINHERITS', inherits) + def handleInclude(statements, filename, lineno, m, force): statements.append(IncludeNode(filename, lineno, m.group(1), force)) @@ -364,6 +374,10 @@ def handleInherit(statements, filename, lineno, m): classes = m.group(1) statements.append(InheritNode(filename, lineno, classes)) +def handleInheritDeferred(statements, filename, lineno, m): + classes = m.group(1) + statements.append(InheritDeferredNode(filename, lineno, classes)) + def runAnonFuncs(d): code = [] for funcname in d.getVar("__BBANONFUNCS", False) or []: @@ -430,6 +444,14 @@ def multi_finalize(fn, d): logger.debug("Appending .bbappend file %s to %s", append, fn) bb.parse.BBHandler.handle(append, d, True) + while True: + inherits = d.getVar('__BBDEFINHERITS', False) or [] + if not inherits: + break + inherit, filename, lineno = inherits.pop(0) + d.setVar('__BBDEFINHERITS', inherits) + bb.parse.BBHandler.inherit(inherit, filename, lineno, d, deferred=True) + onlyfinalise = d.getVar("__ONLYFINALISE", False) safe_d = d diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py index 4d5b45e1ef..cd1c998f8f 100644 --- a/bitbake/lib/bb/parse/parse_py/BBHandler.py +++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py @@ -21,6 +21,7 @@ from .ConfHandler import include, init __func_start_regexp__ = re.compile(r"(((?Ppython(?=(\s|\()))|(?Pfakeroot(?=\s)))\s*)*(?P[\w\.\-\+\{\}\$:]+)?\s*\(\s*\)\s*{$" ) __inherit_regexp__ = re.compile(r"inherit\s+(.+)" ) +__inherit_def_regexp__ = re.compile(r"inherit_defer\s+(.+)" ) __export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" ) __addtask_regexp__ = re.compile(r"addtask\s+(?P\w+)\s*((before\s*(?P((.*(?=after))|(.*))))|(after\s*(?P((.*(?=before))|(.*)))))*") __deltask_regexp__ = re.compile(r"deltask\s+(.+)") @@ -40,8 +41,10 @@ def supports(fn, d): """Return True if fn has a supported extension""" return os.path.splitext(fn)[-1] in [".bb", ".bbclass", ".inc"] -def inherit(files, fn, lineno, d): +def inherit(files, fn, lineno, d, deferred=False): __inherit_cache = d.getVar('__inherit_cache', False) or [] + #if "${" in files and not deferred: + # bb.warn("%s:%s has non deferred conditional inherit" % (fn, lineno)) files = d.expand(files).split() for file in files: classtype = d.getVar("__bbclasstype", False) @@ -265,6 +268,11 @@ def feeder(lineno, s, fn, root, statements, eof=False): ast.handleInherit(statements, fn, lineno, m) return + m = __inherit_def_regexp__.match(s) + if m: + ast.handleInheritDeferred(statements, fn, lineno, m) + return + return ConfHandler.feeder(lineno, s, fn, statements, conffile=False) # Add us to the handlers list