blob: 3a6af325f43753a9dc3d0c2949fe3b39d7a1b82e [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 -050031if sys.argv[0][-5:] == "pydoc":
32 path = os.path.dirname(os.path.dirname(sys.argv[1]))
33else:
34 path = os.path.dirname(os.path.dirname(sys.argv[0]))
35sys.path.insert(0, path)
36from itertools import groupby
37
38from bb import data_smart
39from bb import codeparser
40import bb
41
42logger = data_smart.logger
43_dict_type = data_smart.DataSmart
44
45def init():
46 """Return a new object representing the Bitbake data"""
47 return _dict_type()
48
49def init_db(parent = None):
50 """Return a new object representing the Bitbake data,
51 optionally based on an existing object"""
52 if parent is not None:
53 return parent.createCopy()
54 else:
55 return _dict_type()
56
57def createCopy(source):
58 """Link the source set to the destination
59 If one does not find the value in the destination set,
60 search will go on to the source set to get the value.
61 Value from source are copy-on-write. i.e. any try to
62 modify one of them will end up putting the modified value
63 in the destination set.
64 """
65 return source.createCopy()
66
67def initVar(var, d):
68 """Non-destructive var init for data structure"""
69 d.initVar(var)
70
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071def keys(d):
72 """Return a list of keys in d"""
73 return d.keys()
74
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075def expand(s, d, varname = None):
76 """Variable expansion using the data store"""
77 return d.expand(s, varname)
78
79def expandKeys(alterdata, readdata = None):
Andrew Geissler82c905d2020-04-13 13:39:40 -050080 if readdata is None:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081 readdata = alterdata
82
83 todolist = {}
84 for key in alterdata:
85 if not '${' in key:
86 continue
87
88 ekey = expand(key, readdata)
89 if key == ekey:
90 continue
91 todolist[key] = ekey
92
93 # These two for loops are split for performance to maximise the
94 # usefulness of the expand cache
95 for key in sorted(todolist):
96 ekey = todolist[key]
97 newval = alterdata.getVar(ekey, False)
98 if newval is not None:
99 val = alterdata.getVar(key, False)
100 if val is not None:
101 bb.warn("Variable key %s (%s) replaces original key %s (%s)." % (key, val, ekey, newval))
102 alterdata.renameVar(key, ekey)
103
104def inheritFromOS(d, savedenv, permitted):
105 """Inherit variables from the initial environment."""
106 exportlist = bb.utils.preserved_envvars_exported()
107 for s in savedenv.keys():
108 if s in permitted:
109 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500110 d.setVar(s, savedenv.getVar(s), op = 'from env')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500111 if s in exportlist:
112 d.setVarFlag(s, "export", True, op = 'auto env export')
113 except TypeError:
114 pass
115
116def emit_var(var, o=sys.__stdout__, d = init(), all=False):
117 """Emit a variable to be sourced by a shell."""
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600118 func = d.getVarFlag(var, "func", False)
119 if d.getVarFlag(var, 'python', False) and func:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120 return False
121
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500122 export = d.getVarFlag(var, "export", False)
123 unexport = d.getVarFlag(var, "unexport", False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 if not all and not export and not unexport and not func:
125 return False
126
127 try:
128 if all:
129 oval = d.getVar(var, False)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500130 val = d.getVar(var)
Brad Bishop08902b02019-08-20 09:16:51 -0400131 except (KeyboardInterrupt):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500132 raise
133 except Exception as exc:
134 o.write('# expansion of %s threw %s: %s\n' % (var, exc.__class__.__name__, str(exc)))
135 return False
136
137 if all:
138 d.varhistory.emit(var, oval, val, o, d)
139
140 if (var.find("-") != -1 or var.find(".") != -1 or var.find('{') != -1 or var.find('}') != -1 or var.find('+') != -1) and not all:
141 return False
142
143 varExpanded = d.expand(var)
144
145 if unexport:
146 o.write('unset %s\n' % varExpanded)
147 return False
148
149 if val is None:
150 return False
151
152 val = str(val)
153
154 if varExpanded.startswith("BASH_FUNC_"):
155 varExpanded = varExpanded[10:-2]
156 val = val[3:] # Strip off "() "
157 o.write("%s() %s\n" % (varExpanded, val))
158 o.write("export -f %s\n" % (varExpanded))
159 return True
160
161 if func:
Andrew Geissler635e0e42020-08-21 15:58:33 -0500162 # Write a comment indicating where the shell function came from (line number and filename) to make it easier
163 # for the user to diagnose task failures. This comment is also used by build.py to determine the metadata
164 # location of shell functions.
165 o.write("# line: {0}, file: {1}\n".format(
166 d.getVarFlag(var, "lineno", False),
167 d.getVarFlag(var, "filename", False)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500168 # NOTE: should probably check for unbalanced {} within the var
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500169 val = val.rstrip('\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500170 o.write("%s() {\n%s\n}\n" % (varExpanded, val))
171 return 1
172
173 if export:
174 o.write('export ')
175
176 # if we're going to output this within doublequotes,
177 # to a shell, we need to escape the quotes in the var
178 alter = re.sub('"', '\\"', val)
179 alter = re.sub('\n', ' \\\n', alter)
180 alter = re.sub('\\$', '\\\\$', alter)
181 o.write('%s="%s"\n' % (varExpanded, alter))
182 return False
183
184def emit_env(o=sys.__stdout__, d = init(), all=False):
185 """Emits all items in the data store in a format such that it can be sourced by a shell."""
186
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500187 isfunc = lambda key: bool(d.getVarFlag(key, "func", False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500188 keys = sorted((key for key in d.keys() if not key.startswith("__")), key=isfunc)
189 grouped = groupby(keys, isfunc)
190 for isfunc, keys in grouped:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500191 for key in sorted(keys):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500192 emit_var(key, o, d, all and not isfunc) and o.write('\n')
193
194def exported_keys(d):
195 return (key for key in d.keys() if not key.startswith('__') and
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500196 d.getVarFlag(key, 'export', False) and
197 not d.getVarFlag(key, 'unexport', False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500198
199def exported_vars(d):
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500200 k = list(exported_keys(d))
201 for key in k:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500202 try:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500203 value = d.getVar(key)
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500204 except Exception as err:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500205 bb.warn("%s: Unable to export ${%s}: %s" % (d.getVar("FILE"), key, err))
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500206 continue
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500207
208 if value is not None:
209 yield key, str(value)
210
211def emit_func(func, o=sys.__stdout__, d = init()):
212 """Emits all items in the data store in a format such that it can be sourced by a shell."""
213
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500214 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 -0500215 for key in sorted(keys):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500216 emit_var(key, o, d, False)
217
218 o.write('\n')
219 emit_var(func, o, d, False) and o.write('\n')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500220 newdeps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func))
221 newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500222 seen = set()
223 while newdeps:
224 deps = newdeps
225 seen |= deps
226 newdeps = set()
Patrick Williams93c203f2021-10-06 16:15:23 -0500227 for dep in sorted(deps):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500228 if d.getVarFlag(dep, "func", False) and not d.getVarFlag(dep, "python", False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 emit_var(dep, o, d, False) and o.write('\n')
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500230 newdeps |= bb.codeparser.ShellParser(dep, logger).parse_shell(d.getVar(dep))
231 newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500232 newdeps -= seen
233
234_functionfmt = """
235def {function}(d):
236{body}"""
237
238def emit_func_python(func, o=sys.__stdout__, d = init()):
239 """Emits all items in the data store in a format such that it can be sourced by a shell."""
240
241 def write_func(func, o, call = False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500242 body = d.getVar(func, False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243 if not body.startswith("def"):
244 body = _functionfmt.format(function=func, body=body)
245
246 o.write(body.strip() + "\n\n")
247 if call:
248 o.write(func + "(d)" + "\n\n")
249
250 write_func(func, o, True)
251 pp = bb.codeparser.PythonParser(func, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500252 pp.parse_python(d.getVar(func, False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500253 newdeps = pp.execs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500254 newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500255 seen = set()
256 while newdeps:
257 deps = newdeps
258 seen |= deps
259 newdeps = set()
260 for dep in deps:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500261 if d.getVarFlag(dep, "func", False) and d.getVarFlag(dep, "python", False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500262 write_func(dep, o)
263 pp = bb.codeparser.PythonParser(dep, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500264 pp.parse_python(d.getVar(dep, False))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500265 newdeps |= pp.execs
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500266 newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500267 newdeps -= seen
268
Patrick Williamsde0582f2022-04-08 10:23:27 -0500269def build_dependencies(key, keys, shelldeps, varflagsexcl, ignored_vars, d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500270 deps = set()
271 try:
272 if key[-1] == ']':
273 vf = key[:-1].split('[')
Andrew Geisslerd5838332022-05-27 11:33:10 -0500274 if vf[1] == "vardepvalueexclude":
275 return deps, ""
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800276 value, parser = d.getVarFlag(vf[0], vf[1], False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500277 deps |= parser.references
278 deps = deps | (keys & parser.execs)
279 return deps, value
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600280 varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "exports", "postfuncs", "prefuncs", "lineno", "filename"]) or {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500281 vardeps = varflags.get("vardeps")
Patrick Williamsde0582f2022-04-08 10:23:27 -0500282 exclusions = varflags.get("vardepsexclude", "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500283
Patrick Williamsde0582f2022-04-08 10:23:27 -0500284 def handle_contains(value, contains, exclusions, d):
Andrew Geissler595f6302022-01-24 19:11:47 +0000285 newvalue = []
286 if value:
287 newvalue.append(str(value))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288 for k in sorted(contains):
Patrick Williamsde0582f2022-04-08 10:23:27 -0500289 if k in exclusions or k in ignored_vars:
290 continue
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500291 l = (d.getVar(k) or "").split()
292 for item in sorted(contains[k]):
293 for word in item.split():
294 if not word in l:
Andrew Geissler595f6302022-01-24 19:11:47 +0000295 newvalue.append("\n%s{%s} = Unset" % (k, item))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500296 break
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500297 else:
Andrew Geissler595f6302022-01-24 19:11:47 +0000298 newvalue.append("\n%s{%s} = Set" % (k, item))
299 return "".join(newvalue)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500300
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800301 def handle_remove(value, deps, removes, d):
302 for r in sorted(removes):
303 r2 = d.expandWithRefs(r, None)
304 value += "\n_remove of %s" % r
305 deps |= r2.references
306 deps = deps | (keys & r2.execs)
307 return value
308
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500309 if "vardepvalue" in varflags:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800310 value = varflags.get("vardepvalue")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311 elif varflags.get("func"):
312 if varflags.get("python"):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800313 value = d.getVarFlag(key, "_content", False)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314 parser = bb.codeparser.PythonParser(key, logger)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500315 parser.parse_python(value, filename=varflags.get("filename"), lineno=varflags.get("lineno"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500316 deps = deps | parser.references
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500317 deps = deps | (keys & parser.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500318 value = handle_contains(value, parser.contains, exclusions, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500319 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800320 value, parsedvar = d.getVarFlag(key, "_content", False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500321 parser = bb.codeparser.ShellParser(key, logger)
322 parser.parse_shell(parsedvar.value)
323 deps = deps | shelldeps
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500324 deps = deps | parsedvar.references
325 deps = deps | (keys & parser.execs) | (keys & parsedvar.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500326 value = handle_contains(value, parsedvar.contains, exclusions, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800327 if hasattr(parsedvar, "removes"):
328 value = handle_remove(value, deps, parsedvar.removes, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500329 if vardeps is None:
330 parser.log.flush()
331 if "prefuncs" in varflags:
332 deps = deps | set(varflags["prefuncs"].split())
333 if "postfuncs" in varflags:
334 deps = deps | set(varflags["postfuncs"].split())
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600335 if "exports" in varflags:
336 deps = deps | set(varflags["exports"].split())
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500337 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800338 value, parser = d.getVarFlag(key, "_content", False, retparser=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500339 deps |= parser.references
340 deps = deps | (keys & parser.execs)
Patrick Williamsde0582f2022-04-08 10:23:27 -0500341 value = handle_contains(value, parser.contains, exclusions, d)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800342 if hasattr(parser, "removes"):
343 value = handle_remove(value, deps, parser.removes, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500344
345 if "vardepvalueexclude" in varflags:
346 exclude = varflags.get("vardepvalueexclude")
347 for excl in exclude.split('|'):
348 if excl:
349 value = value.replace(excl, '')
350
351 # Add varflags, assuming an exclusion list is set
352 if varflagsexcl:
353 varfdeps = []
354 for f in varflags:
355 if f not in varflagsexcl:
356 varfdeps.append('%s[%s]' % (key, f))
357 if varfdeps:
358 deps |= set(varfdeps)
359
360 deps |= set((vardeps or "").split())
Patrick Williamsde0582f2022-04-08 10:23:27 -0500361 deps -= set(exclusions)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500362 except bb.parse.SkipRecipe:
363 raise
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500364 except Exception as e:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500365 bb.warn("Exception during build_dependencies for %s" % key)
366 raise
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500367 return deps, value
368 #bb.note("Variable %s references %s and calls %s" % (key, str(deps), str(execs)))
369 #d.setVarFlag(key, "vardeps", deps)
370
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000371def generate_dependencies(d, ignored_vars):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500372
373 keys = set(key for key in d if not key.startswith("__"))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500374 shelldeps = set(key for key in d.getVar("__exportlist", False) if d.getVarFlag(key, "export", False) and not d.getVarFlag(key, "unexport", False))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500375 varflagsexcl = d.getVar('BB_SIGNATURE_EXCLUDE_FLAGS')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376
377 deps = {}
378 values = {}
379
380 tasklist = d.getVar('__BBTASKS', False) or []
381 for task in tasklist:
Patrick Williamsde0582f2022-04-08 10:23:27 -0500382 deps[task], values[task] = build_dependencies(task, keys, shelldeps, varflagsexcl, ignored_vars, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500383 newdeps = deps[task]
384 seen = set()
385 while newdeps:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000386 nextdeps = newdeps - ignored_vars
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500387 seen |= nextdeps
388 newdeps = set()
389 for dep in nextdeps:
390 if dep not in deps:
Patrick Williamsde0582f2022-04-08 10:23:27 -0500391 deps[dep], values[dep] = build_dependencies(dep, keys, shelldeps, varflagsexcl, ignored_vars, d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500392 newdeps |= deps[dep]
393 newdeps -= seen
394 #print "For %s: %s" % (task, str(deps[task]))
395 return tasklist, deps, values
396
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000397def generate_dependency_hash(tasklist, gendeps, lookupcache, ignored_vars, fn):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800398 taskdeps = {}
399 basehash = {}
400
401 for task in tasklist:
402 data = lookupcache[task]
403
404 if data is None:
405 bb.error("Task %s from %s seems to be empty?!" % (task, fn))
Andrew Geissler595f6302022-01-24 19:11:47 +0000406 data = []
407 else:
408 data = [data]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800409
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000410 gendeps[task] -= ignored_vars
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800411 newdeps = gendeps[task]
412 seen = set()
413 while newdeps:
414 nextdeps = newdeps
415 seen |= nextdeps
416 newdeps = set()
417 for dep in nextdeps:
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000418 if dep in ignored_vars:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800419 continue
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000420 gendeps[dep] -= ignored_vars
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800421 newdeps |= gendeps[dep]
422 newdeps -= seen
423
424 alldeps = sorted(seen)
425 for dep in alldeps:
Andrew Geissler595f6302022-01-24 19:11:47 +0000426 data.append(dep)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800427 var = lookupcache[dep]
428 if var is not None:
Andrew Geissler595f6302022-01-24 19:11:47 +0000429 data.append(str(var))
Brad Bishop08902b02019-08-20 09:16:51 -0400430 k = fn + ":" + task
Andrew Geissler595f6302022-01-24 19:11:47 +0000431 basehash[k] = hashlib.sha256("".join(data).encode("utf-8")).hexdigest()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800432 taskdeps[task] = alldeps
433
434 return taskdeps, basehash
435
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436def inherits_class(klass, d):
437 val = d.getVar('__inherit_cache', False) or []
Patrick Williams92b42cb2022-09-03 06:53:57 -0500438 needle = '/%s.bbclass' % klass
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500439 for v in val:
440 if v.endswith(needle):
441 return True
442 return False