blob: 505f42950fff539d287d23c372a33037ac8b5631 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"""
2BitBake 'Data' implementations
3
4Functions for interacting with the data structure used by the
5BitBake build tools.
6
Patrick Williams7784c422022-11-17 07:29:11 -06007expandKeys and datastore iteration are the most expensive
8operations. Updating overrides is now "on the fly" but still based
9on the idea of the cookie monster introduced by zecke:
10"At night the cookie monster came by and
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011suggested 'give me cookies on setting the variables and
12things will work out'. Taking this suggestion into account
13applying the skills from the not yet passed 'Entwurf und
14Analyse von Algorithmen' lecture and the cookie
15monster seems to be right. We will track setVar more carefully
Patrick Williams7784c422022-11-17 07:29:11 -060016to have faster datastore operations."
Patrick Williamsc124f4f2015-09-15 14:41:29 -050017
18This is a trade-off between speed and memory again but
19the speed is more critical here.
20"""
21
22# Copyright (C) 2003, 2004 Chris Larson
23# Copyright (C) 2005 Holger Hans Peter Freyther
24#
Brad Bishopc342db32019-05-15 21:57:59 -040025# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050026#
27# Based on functions from the base bb module, Copyright 2003 Holger Schurig
28
29import sys, os, re
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080030import hashlib
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031from itertools import groupby
32
33from bb import data_smart
34from bb import codeparser
35import bb
36
37logger = data_smart.logger
38_dict_type = data_smart.DataSmart
39
40def init():
41 """Return a new object representing the Bitbake data"""
42 return _dict_type()
43
44def init_db(parent = None):
45 """Return a new object representing the Bitbake data,
46 optionally based on an existing object"""
47 if parent is not None:
48 return parent.createCopy()
49 else:
50 return _dict_type()
51
52def createCopy(source):
53 """Link the source set to the destination
54 If one does not find the value in the destination set,
55 search will go on to the source set to get the value.
56 Value from source are copy-on-write. i.e. any try to
57 modify one of them will end up putting the modified value
58 in the destination set.
59 """
60 return source.createCopy()
61
62def initVar(var, d):
63 """Non-destructive var init for data structure"""
64 d.initVar(var)
65
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066def keys(d):
67 """Return a list of keys in d"""
68 return d.keys()
69
Patrick Williamsc124f4f2015-09-15 14:41:29 -050070def expand(s, d, varname = None):
71 """Variable expansion using the data store"""
72 return d.expand(s, varname)
73
74def expandKeys(alterdata, readdata = None):
Andrew Geissler82c905d2020-04-13 13:39:40 -050075 if readdata is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076 readdata = alterdata
77
78 todolist = {}
79 for key in alterdata:
80 if not '${' in key:
81 continue
82
83 ekey = expand(key, readdata)
84 if key == ekey:
85 continue
86 todolist[key] = ekey
87
88 # These two for loops are split for performance to maximise the
89 # usefulness of the expand cache
90 for key in sorted(todolist):
91 ekey = todolist[key]
92 newval = alterdata.getVar(ekey, False)
93 if newval is not None:
94 val = alterdata.getVar(key, False)
95 if val is not None:
96 bb.warn("Variable key %s (%s) replaces original key %s (%s)." % (key, val, ekey, newval))
97 alterdata.renameVar(key, ekey)
98
99def inheritFromOS(d, savedenv, permitted):
100 """Inherit variables from the initial environment."""
101 exportlist = bb.utils.preserved_envvars_exported()
102 for s in savedenv.keys():
103 if s in permitted:
104 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500105 d.setVar(s, savedenv.getVar(s), op = 'from env')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106 if s in exportlist:
107 d.setVarFlag(s, "export", True, op = 'auto env export')
108 except TypeError:
109 pass
110
111def emit_var(var, o=sys.__stdout__, d = init(), all=False):
112 """Emit a variable to be sourced by a shell."""
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600113 func = d.getVarFlag(var, "func", False)
114 if d.getVarFlag(var, 'python', False) and func:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115 return False
116
Andrew Geissler6aa7eec2023-03-03 12:41:14 -0600117 export = bb.utils.to_boolean(d.getVarFlag(var, "export"))
118 unexport = bb.utils.to_boolean(d.getVarFlag(var, "unexport"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500119 if not all and not export and not unexport and not func:
120 return False
121
122 try:
123 if all:
124 oval = d.getVar(var, False)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500125 val = d.getVar(var)
Brad Bishop08902b02019-08-20 09:16:51 -0400126 except (KeyboardInterrupt):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500127 raise
128 except Exception as exc:
129 o.write('# expansion of %s threw %s: %s\n' % (var, exc.__class__.__name__, str(exc)))
130 return False
131
132 if all:
133 d.varhistory.emit(var, oval, val, o, d)
134
135 if (var.find("-") != -1 or var.find(".") != -1 or var.find('{') != -1 or var.find('}') != -1 or var.find('+') != -1) and not all:
136 return False
137
138 varExpanded = d.expand(var)
139
140 if unexport:
141 o.write('unset %s\n' % varExpanded)
142 return False
143
144 if val is None:
145 return False
146
147 val = str(val)
148
149 if varExpanded.startswith("BASH_FUNC_"):
150 varExpanded = varExpanded[10:-2]
151 val = val[3:] # Strip off "() "
152 o.write("%s() %s\n" % (varExpanded, val))
153 o.write("export -f %s\n" % (varExpanded))
154 return True
155
156 if func:
Andrew Geissler635e0e42020-08-21 15:58:33 -0500157 # Write a comment indicating where the shell function came from (line number and filename) to make it easier
158 # for the user to diagnose task failures. This comment is also used by build.py to determine the metadata
159 # location of shell functions.
160 o.write("# line: {0}, file: {1}\n".format(
161 d.getVarFlag(var, "lineno", False),
162 d.getVarFlag(var, "filename", False)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500163 # NOTE: should probably check for unbalanced {} within the var
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500164 val = val.rstrip('\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500165 o.write("%s() {\n%s\n}\n" % (varExpanded, val))
166 return 1
167
168 if export:
169 o.write('export ')
170
171 # if we're going to output this within doublequotes,
172 # to a shell, we need to escape the quotes in the var
173 alter = re.sub('"', '\\"', val)
174 alter = re.sub('\n', ' \\\n', alter)
175 alter = re.sub('\\$', '\\\\$', alter)
176 o.write('%s="%s"\n' % (varExpanded, alter))
177 return False
178
179def emit_env(o=sys.__stdout__, d = init(), all=False):
180 """Emits all items in the data store in a format such that it can be sourced by a shell."""
181
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500182 isfunc = lambda key: bool(d.getVarFlag(key, "func", False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500183 keys = sorted((key for key in d.keys() if not key.startswith("__")), key=isfunc)
184 grouped = groupby(keys, isfunc)
185 for isfunc, keys in grouped:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500186 for key in sorted(keys):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500187 emit_var(key, o, d, all and not isfunc) and o.write('\n')
188
189def exported_keys(d):
190 return (key for key in d.keys() if not key.startswith('__') and
Andrew Geissler6aa7eec2023-03-03 12:41:14 -0600191 bb.utils.to_boolean(d.getVarFlag(key, 'export')) and
192 not bb.utils.to_boolean(d.getVarFlag(key, 'unexport')))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500193
194def exported_vars(d):
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500195 k = list(exported_keys(d))
196 for key in k:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500197 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500198 value = d.getVar(key)
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500199 except Exception as err:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500200 bb.warn("%s: Unable to export ${%s}: %s" % (d.getVar("FILE"), key, err))
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500201 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500202
203 if value is not None:
204 yield key, str(value)
205
206def emit_func(func, o=sys.__stdout__, d = init()):
207 """Emits all items in the data store in a format such that it can be sourced by a shell."""
208
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500209 keys = (key for key in d.keys() if not key.startswith("__") and not d.getVarFlag(key, "func", False))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500210 for key in sorted(keys):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500211 emit_var(key, o, d, False)
212
213 o.write('\n')
214 emit_var(func, o, d, False) and o.write('\n')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500215 newdeps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func))
216 newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500217 seen = set()
218 while newdeps:
219 deps = newdeps
220 seen |= deps
221 newdeps = set()
Patrick Williams93c203f2021-10-06 16:15:23 -0500222 for dep in sorted(deps):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500223 if d.getVarFlag(dep, "func", False) and not d.getVarFlag(dep, "python", False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500224 emit_var(dep, o, d, False) and o.write('\n')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500225 newdeps |= bb.codeparser.ShellParser(dep, logger).parse_shell(d.getVar(dep))
226 newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500227 newdeps -= seen
228
229_functionfmt = """
230def {function}(d):
231{body}"""
232
233def emit_func_python(func, o=sys.__stdout__, d = init()):
234 """Emits all items in the data store in a format such that it can be sourced by a shell."""
235
236 def write_func(func, o, call = False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500237 body = d.getVar(func, False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238 if not body.startswith("def"):
239 body = _functionfmt.format(function=func, body=body)
240
241 o.write(body.strip() + "\n\n")
242 if call:
243 o.write(func + "(d)" + "\n\n")
244
245 write_func(func, o, True)
246 pp = bb.codeparser.PythonParser(func, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500247 pp.parse_python(d.getVar(func, False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248 newdeps = pp.execs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500249 newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 seen = set()
251 while newdeps:
252 deps = newdeps
253 seen |= deps
254 newdeps = set()
255 for dep in deps:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500256 if d.getVarFlag(dep, "func", False) and d.getVarFlag(dep, "python", False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500257 write_func(dep, o)
258 pp = bb.codeparser.PythonParser(dep, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500259 pp.parse_python(d.getVar(dep, False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500260 newdeps |= pp.execs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500261 newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500262 newdeps -= seen
263
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600264def build_dependencies(key, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d, codeparsedata):
Andrew Geissler517393d2023-01-13 08:55:19 -0600265 def handle_contains(value, contains, exclusions, d):
266 newvalue = []
267 if value:
268 newvalue.append(str(value))
269 for k in sorted(contains):
270 if k in exclusions or k in ignored_vars:
271 continue
272 l = (d.getVar(k) or "").split()
273 for item in sorted(contains[k]):
274 for word in item.split():
275 if not word in l:
276 newvalue.append("\n%s{%s} = Unset" % (k, item))
277 break
278 else:
279 newvalue.append("\n%s{%s} = Set" % (k, item))
280 return "".join(newvalue)
281
282 def handle_remove(value, deps, removes, d):
283 for r in sorted(removes):
284 r2 = d.expandWithRefs(r, None)
285 value += "\n_remove of %s" % r
286 deps |= r2.references
287 deps = deps | (keys & r2.execs)
Andrew Geissler220dafd2023-10-04 10:18:08 -0500288 value = handle_contains(value, r2.contains, exclusions, d)
Andrew Geissler517393d2023-01-13 08:55:19 -0600289 return value
290
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291 deps = set()
292 try:
Andrew Geissler517393d2023-01-13 08:55:19 -0600293 if key in mod_funcs:
294 exclusions = set()
295 moddep = bb.codeparser.modulecode_deps[key]
296 value = handle_contains("", moddep[3], exclusions, d)
297 return frozenset((moddep[0] | keys & moddep[1]) - ignored_vars), value
298
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500299 if key[-1] == ']':
300 vf = key[:-1].split('[')
Andrew Geisslerd5838332022-05-27 11:33:10 -0500301 if vf[1] == "vardepvalueexclude":
302 return deps, ""
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800303 value, parser = d.getVarFlag(vf[0], vf[1], False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500304 deps |= parser.references
305 deps = deps | (keys & parser.execs)
Andrew Geissler517393d2023-01-13 08:55:19 -0600306 deps -= ignored_vars
307 return frozenset(deps), value
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600308 varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "exports", "postfuncs", "prefuncs", "lineno", "filename"]) or {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500309 vardeps = varflags.get("vardeps")
Patrick Williamsde0582f2022-04-08 10:23:27 -0500310 exclusions = varflags.get("vardepsexclude", "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500312 if "vardepvalue" in varflags:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800313 value = varflags.get("vardepvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314 elif varflags.get("func"):
315 if varflags.get("python"):
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600316 value = codeparsedata.getVarFlag(key, "_content", False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500317 parser = bb.codeparser.PythonParser(key, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500318 parser.parse_python(value, filename=varflags.get("filename"), lineno=varflags.get("lineno"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500319 deps = deps | parser.references
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500320 deps = deps | (keys & parser.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500321 value = handle_contains(value, parser.contains, exclusions, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500322 else:
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600323 value, parsedvar = codeparsedata.getVarFlag(key, "_content", False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500324 parser = bb.codeparser.ShellParser(key, logger)
325 parser.parse_shell(parsedvar.value)
326 deps = deps | shelldeps
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500327 deps = deps | parsedvar.references
328 deps = deps | (keys & parser.execs) | (keys & parsedvar.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500329 value = handle_contains(value, parsedvar.contains, exclusions, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800330 if hasattr(parsedvar, "removes"):
331 value = handle_remove(value, deps, parsedvar.removes, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500332 if vardeps is None:
333 parser.log.flush()
334 if "prefuncs" in varflags:
335 deps = deps | set(varflags["prefuncs"].split())
336 if "postfuncs" in varflags:
337 deps = deps | set(varflags["postfuncs"].split())
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600338 if "exports" in varflags:
339 deps = deps | set(varflags["exports"].split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500340 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800341 value, parser = d.getVarFlag(key, "_content", False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500342 deps |= parser.references
343 deps = deps | (keys & parser.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500344 value = handle_contains(value, parser.contains, exclusions, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800345 if hasattr(parser, "removes"):
346 value = handle_remove(value, deps, parser.removes, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500347
348 if "vardepvalueexclude" in varflags:
349 exclude = varflags.get("vardepvalueexclude")
350 for excl in exclude.split('|'):
351 if excl:
352 value = value.replace(excl, '')
353
354 # Add varflags, assuming an exclusion list is set
355 if varflagsexcl:
356 varfdeps = []
357 for f in varflags:
358 if f not in varflagsexcl:
359 varfdeps.append('%s[%s]' % (key, f))
360 if varfdeps:
361 deps |= set(varfdeps)
362
363 deps |= set((vardeps or "").split())
Patrick Williamsde0582f2022-04-08 10:23:27 -0500364 deps -= set(exclusions)
Andrew Geissler517393d2023-01-13 08:55:19 -0600365 deps -= ignored_vars
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500366 except bb.parse.SkipRecipe:
367 raise
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368 except Exception as e:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500369 bb.warn("Exception during build_dependencies for %s" % key)
370 raise
Andrew Geissler517393d2023-01-13 08:55:19 -0600371 return frozenset(deps), value
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500372 #bb.note("Variable %s references %s and calls %s" % (key, str(deps), str(execs)))
373 #d.setVarFlag(key, "vardeps", deps)
374
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000375def generate_dependencies(d, ignored_vars):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
Andrew Geissler517393d2023-01-13 08:55:19 -0600377 mod_funcs = set(bb.codeparser.modulecode_deps.keys())
378 keys = set(key for key in d if not key.startswith("__")) | mod_funcs
Andrew Geissler6aa7eec2023-03-03 12:41:14 -0600379 shelldeps = set(key for key in d.getVar("__exportlist", False) if bb.utils.to_boolean(d.getVarFlag(key, "export")) and not bb.utils.to_boolean(d.getVarFlag(key, "unexport")))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500380 varflagsexcl = d.getVar('BB_SIGNATURE_EXCLUDE_FLAGS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500381
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600382 codeparserd = d.createCopy()
383 for forced in (d.getVar('BB_HASH_CODEPARSER_VALS') or "").split():
384 key, value = forced.split("=", 1)
385 codeparserd.setVar(key, value)
386
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500387 deps = {}
388 values = {}
389
390 tasklist = d.getVar('__BBTASKS', False) or []
391 for task in tasklist:
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600392 deps[task], values[task] = build_dependencies(task, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d, codeparserd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500393 newdeps = deps[task]
394 seen = set()
395 while newdeps:
Andrew Geissler517393d2023-01-13 08:55:19 -0600396 nextdeps = newdeps
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500397 seen |= nextdeps
398 newdeps = set()
399 for dep in nextdeps:
400 if dep not in deps:
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600401 deps[dep], values[dep] = build_dependencies(dep, keys, mod_funcs, shelldeps, varflagsexcl, ignored_vars, d, codeparserd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500402 newdeps |= deps[dep]
403 newdeps -= seen
404 #print "For %s: %s" % (task, str(deps[task]))
405 return tasklist, deps, values
406
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000407def generate_dependency_hash(tasklist, gendeps, lookupcache, ignored_vars, fn):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800408 taskdeps = {}
409 basehash = {}
410
411 for task in tasklist:
412 data = lookupcache[task]
413
414 if data is None:
415 bb.error("Task %s from %s seems to be empty?!" % (task, fn))
Andrew Geissler595f6302022-01-24 19:11:47 +0000416 data = []
417 else:
418 data = [data]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800419
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800420 newdeps = gendeps[task]
421 seen = set()
422 while newdeps:
423 nextdeps = newdeps
424 seen |= nextdeps
425 newdeps = set()
426 for dep in nextdeps:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800427 newdeps |= gendeps[dep]
428 newdeps -= seen
429
430 alldeps = sorted(seen)
431 for dep in alldeps:
Andrew Geissler595f6302022-01-24 19:11:47 +0000432 data.append(dep)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800433 var = lookupcache[dep]
434 if var is not None:
Andrew Geissler595f6302022-01-24 19:11:47 +0000435 data.append(str(var))
Brad Bishop08902b02019-08-20 09:16:51 -0400436 k = fn + ":" + task
Andrew Geissler595f6302022-01-24 19:11:47 +0000437 basehash[k] = hashlib.sha256("".join(data).encode("utf-8")).hexdigest()
Andrew Geissler517393d2023-01-13 08:55:19 -0600438 taskdeps[task] = frozenset(seen)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800439
440 return taskdeps, basehash
441
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500442def inherits_class(klass, d):
443 val = d.getVar('__inherit_cache', False) or []
Patrick Williams92b42cb2022-09-03 06:53:57 -0500444 needle = '/%s.bbclass' % klass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500445 for v in val:
446 if v.endswith(needle):
447 return True
448 return False