diff options
Diffstat (limited to 'bitbake/lib/bb/siggen.py')
-rw-r--r-- | bitbake/lib/bb/siggen.py | 98 |
1 files changed, 65 insertions, 33 deletions
diff --git a/bitbake/lib/bb/siggen.py b/bitbake/lib/bb/siggen.py index 48f600a212..a101ce8bb3 100644 --- a/bitbake/lib/bb/siggen.py +++ b/bitbake/lib/bb/siggen.py @@ -1,53 +1,63 @@ import hashlib +import logging import re +logger = logging.getLogger('BitBake.SigGen') + try: import cPickle as pickle except ImportError: import pickle - bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.") + logger.info('Importing cPickle failed. Falling back to a very slow implementation.') -def init(d, dumpsigs): +def init(d): siggens = [obj for obj in globals().itervalues() if type(obj) is type and issubclass(obj, SignatureGenerator)] desired = bb.data.getVar("BB_SIGNATURE_HANDLER", d, True) or "noop" for sg in siggens: if desired == sg.name: - return sg(d, dumpsigs) + return sg(d) break else: - bb.error("Invalid signature generator '%s', using default 'noop' generator" % desired) - bb.error("Available generators: %s" % ", ".join(obj.name for obj in siggens)) - return SignatureGenerator(d, dumpsigs) + logger.error("Invalid signature generator '%s', using default 'noop'\n" + "Available generators: %s", + ', '.join(obj.name for obj in siggens)) + return SignatureGenerator(d) class SignatureGenerator(object): """ """ name = "noop" - def __init__(self, data, dumpsigs): + def __init__(self, data): return def finalise(self, fn, d, varient): return - def stampfile(self, stampbase, taskname, taskhash): - return "%s.%s" % (stampbase, taskname) + def get_taskhash(self, fn, task, deps, dataCache): + return 0 + + def set_taskdata(self, hashes, deps): + return + + def stampfile(self, stampbase, file_name, taskname, extrainfo): + return ("%s.%s.%s" % (stampbase, taskname, extrainfo)).rstrip('.') class SignatureGeneratorBasic(SignatureGenerator): """ """ name = "basic" - def __init__(self, data, dumpsigs): + def __init__(self, data): self.basehash = {} self.taskhash = {} self.taskdeps = {} self.runtaskdeps = {} self.gendeps = {} self.lookupcache = {} - self.basewhitelist = (data.getVar("BB_HASHBASE_WHITELIST", True) or "").split() + self.basewhitelist = set((data.getVar("BB_HASHBASE_WHITELIST", True) or "").split()) self.taskwhitelist = data.getVar("BB_HASHTASK_WHITELIST", True) or None if self.taskwhitelist: @@ -57,17 +67,31 @@ class SignatureGeneratorBasic(SignatureGenerator): def _build_data(self, fn, d): - taskdeps, gendeps = bb.data.generate_dependencies(d) + tasklist, gendeps = bb.data.generate_dependencies(d) + taskdeps = {} basehash = {} lookupcache = {} - for task in taskdeps: + for task in tasklist: data = d.getVar(task, False) lookupcache[task] = data - for dep in sorted(taskdeps[task]): - if dep in self.basewhitelist: - continue + + newdeps = gendeps[task] + seen = set() + while newdeps: + nextdeps = newdeps + seen |= nextdeps + newdeps = set() + for dep in nextdeps: + if dep in self.basewhitelist: + continue + newdeps |= gendeps[dep] + newdeps -= seen + + alldeps = seen - self.basewhitelist + + for dep in sorted(alldeps): if dep in lookupcache: var = lookupcache[dep] else: @@ -78,7 +102,7 @@ class SignatureGeneratorBasic(SignatureGenerator): if data is None: bb.error("Task %s from %s seems to be empty?!" % (task, fn)) self.basehash[fn + "." + task] = hashlib.md5(data).hexdigest() - #bb.note("Hash for %s is %s" % (task, tashhash[task])) + taskdeps[task] = sorted(alldeps) self.taskdeps[fn] = taskdeps self.gendeps[fn] = gendeps @@ -110,7 +134,6 @@ class SignatureGeneratorBasic(SignatureGenerator): # then process the actual dependencies dep_fn = re.search("(?P<fn>.*)\..*", dep).group('fn') if self.twl.search(dataCache.pkg_fn[dep_fn]): - #bb.note("Skipping %s" % dep) continue if dep not in self.taskhash: bb.fatal("%s is not in taskhash, caller isn't calling in dependency order?", dep) @@ -170,6 +193,17 @@ class SignatureGeneratorBasic(SignatureGenerator): bb.error("The mismatched hashes were %s and %s" % (dataCache.basetaskhash[k], self.basehash[k])) self.dump_sigtask(fn, task, dataCache.stamp[fn], True) +class SignatureGeneratorBasicHash(SignatureGeneratorBasic): + name = "basichash" + + def stampfile(self, stampbase, fn, taskname, extrainfo): + if taskname != "do_setscene" and taskname.endswith("_setscene"): + k = fn + "." + taskname[:-9] + else: + k = fn + "." + taskname + h = self.taskhash[k] + return ("%s.%s.%s.%s" % (stampbase, taskname, h, extrainfo)).rstrip('.') + def dump_this_task(outfile, d): fn = d.getVar("BB_FILENAME", True) task = "do_" + d.getVar("BB_CURRENTTASK", True) @@ -181,10 +215,6 @@ def compare_sigfiles(a, b): p2 = pickle.Unpickler(file(b, "rb")) b_data = p2.load() - #print "Checking" - #print str(a_data) - #print str(b_data) - def dict_diff(a, b): sa = set(a.keys()) sb = set(b.keys()) @@ -195,7 +225,7 @@ def compare_sigfiles(a, b): changed.add(i) added = sa - sb removed = sb - sa - return changed, added, removed + return changed, added, removed if 'basewhitelist' in a_data and a_data['basewhitelist'] != b_data['basewhitelist']: print "basewhitelist changed from %s to %s" % (a_data['basewhitelist'], b_data['basewhitelist']) @@ -225,18 +255,20 @@ def compare_sigfiles(a, b): if changed: for dep in changed: print "Variable %s value changed from %s to %s" % (dep, a_data['varvals'][dep], b_data['varvals'][dep]) - #if added: - # print "Dependency on variable %s was added (value %s)" % (dep, b_data['gendeps'][dep]) - #if removed: - # print "Dependency on Variable %s was removed (value %s)" % (dep, a_data['gendeps'][dep]) - if 'runtaskdeps' in a_data and 'runtaskdeps' in b_data and sorted(a_data['runtaskdeps']) != sorted(b_data['runtaskdeps']): - print "Tasks this task depends on changed from %s to %s" % (sorted(a_data['runtaskdeps']), sorted(b_data['runtaskdeps'])) - - if 'runtaskhashes' in a_data: - for dep in a_data['runtaskhashes']: - if a_data['runtaskhashes'][dep] != b_data['runtaskhashes'][dep]: + if 'runtaskhashes' in a_data and 'runtaskhashes' in b_data: + changed, added, removed = dict_diff(a_data['runtaskhashes'], b_data['runtaskhashes']) + if added: + for dep in added: + print "Dependency on task %s was added" % (dep) + if removed: + for dep in removed: + print "Dependency on task %s was removed" % (dep) + if changed: + for dep in changed: print "Hash for dependent task %s changed from %s to %s" % (dep, a_data['runtaskhashes'][dep], b_data['runtaskhashes'][dep]) + elif 'runtaskdeps' in a_data and 'runtaskdeps' in b_data and sorted(a_data['runtaskdeps']) != sorted(b_data['runtaskdeps']): + print "Tasks this task depends on changed from %s to %s" % (sorted(a_data['runtaskdeps']), sorted(b_data['runtaskdeps'])) def dump_sigfile(a): p1 = pickle.Unpickler(file(a, "rb")) |