summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/codeparser.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2024-08-28 12:54:30 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-08-29 21:58:19 +0100
commit9a25a38ffe4acb374312ea86fdb0587bcc0f5f57 (patch)
tree8276fc3159f2131a9988f93810eed1ea0aa03514 /bitbake/lib/bb/codeparser.py
parent3492e96032d9a2883d756b752313047ddee8a779 (diff)
downloadpoky-9a25a38ffe4acb374312ea86fdb0587bcc0f5f57.tar.gz
bitbake: codeparser: Allow code visitor expressions to be declared in metadata
Allow the metadata to define code visitor expressions which mean that custom dependencies can be handled in function libraries. An example is the qa.handle_error function in OE which can set something like: """ def handle_error_visitorcode(name, args): execs = set() contains = {} warn = None if isinstance(args[0], ast.Constant) and isinstance(args[0].value, str): for i in ["ERROR_QA", "WARN_QA"]: if i not in contains: contains[i] = set() contains[i].add(args[0].value) else: warn = args[0] execs.add(name) return contains, execs, warn handle_error.visitorcode = handle_error_visitorcode """ Meaning that it can have contains optimisations on ERROR and WARN_QA instead of hard dependencies. One drawback to this solution is the parsing order. Functions with visitorcode need to be defined before anything else references them or the visitor code will not function for the earlier references. (Bitbake rev: 5bd0c65c217394cde4c8e382eba6cf7f4b909c97) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/codeparser.py')
-rw-r--r--bitbake/lib/bb/codeparser.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/bitbake/lib/bb/codeparser.py b/bitbake/lib/bb/codeparser.py
index b25a2133d2..d249af326e 100644
--- a/bitbake/lib/bb/codeparser.py
+++ b/bitbake/lib/bb/codeparser.py
@@ -87,14 +87,17 @@ def add_module_functions(fn, functions, namespace):
87 if e in functions: 87 if e in functions:
88 execs.remove(e) 88 execs.remove(e)
89 execs.add(namespace + "." + e) 89 execs.add(namespace + "." + e)
90 modulecode_deps[name] = [parser.references.copy(), execs, parser.var_execs.copy(), parser.contains.copy(), parser.extra] 90 visitorcode = None
91 if hasattr(functions[f], 'visitorcode'):
92 visitorcode = getattr(functions[f], "visitorcode")
93 modulecode_deps[name] = [parser.references.copy(), execs, parser.var_execs.copy(), parser.contains.copy(), parser.extra, visitorcode]
91 #bb.warn("%s: %s\nRefs:%s Execs: %s %s %s" % (name, fn, parser.references, parser.execs, parser.var_execs, parser.contains)) 94 #bb.warn("%s: %s\nRefs:%s Execs: %s %s %s" % (name, fn, parser.references, parser.execs, parser.var_execs, parser.contains))
92 95
93def update_module_dependencies(d): 96def update_module_dependencies(d):
94 for mod in modulecode_deps: 97 for mod in modulecode_deps:
95 excludes = set((d.getVarFlag(mod, "vardepsexclude") or "").split()) 98 excludes = set((d.getVarFlag(mod, "vardepsexclude") or "").split())
96 if excludes: 99 if excludes:
97 modulecode_deps[mod] = [modulecode_deps[mod][0] - excludes, modulecode_deps[mod][1] - excludes, modulecode_deps[mod][2] - excludes, modulecode_deps[mod][3], modulecode_deps[mod][4]] 100 modulecode_deps[mod] = [modulecode_deps[mod][0] - excludes, modulecode_deps[mod][1] - excludes, modulecode_deps[mod][2] - excludes, modulecode_deps[mod][3], modulecode_deps[mod][4], modulecode_deps[mod][5]]
98 101
99# A custom getstate/setstate using tuples is actually worth 15% cachesize by 102# A custom getstate/setstate using tuples is actually worth 15% cachesize by
100# avoiding duplication of the attribute names! 103# avoiding duplication of the attribute names!
@@ -161,7 +164,7 @@ class CodeParserCache(MultiProcessCache):
161 # so that an existing cache gets invalidated. Additionally you'll need 164 # so that an existing cache gets invalidated. Additionally you'll need
162 # to increment __cache_version__ in cache.py in order to ensure that old 165 # to increment __cache_version__ in cache.py in order to ensure that old
163 # recipe caches don't trigger "Taskhash mismatch" errors. 166 # recipe caches don't trigger "Taskhash mismatch" errors.
164 CACHE_VERSION = 12 167 CACHE_VERSION = 14
165 168
166 def __init__(self): 169 def __init__(self):
167 MultiProcessCache.__init__(self) 170 MultiProcessCache.__init__(self)
@@ -261,7 +264,15 @@ class PythonParser():
261 264
262 def visit_Call(self, node): 265 def visit_Call(self, node):
263 name = self.called_node_name(node.func) 266 name = self.called_node_name(node.func)
264 if name and (name.endswith(self.getvars) or name.endswith(self.getvarflags) or name in self.containsfuncs or name in self.containsanyfuncs): 267 if name and name in modulecode_deps and modulecode_deps[name][5]:
268 visitorcode = modulecode_deps[name][5]
269 contains, execs, warn = visitorcode(name, node.args)
270 for i in contains:
271 self.contains[i] = contains[i]
272 self.execs |= execs
273 if warn:
274 self.warn(node.func, warn)
275 elif name and (name.endswith(self.getvars) or name.endswith(self.getvarflags) or name in self.containsfuncs or name in self.containsanyfuncs):
265 if isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str): 276 if isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str):
266 varname = node.args[0].value 277 varname = node.args[0].value
267 if name in self.containsfuncs and isinstance(node.args[1], ast.Constant): 278 if name in self.containsfuncs and isinstance(node.args[1], ast.Constant):