diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-12-19 09:40:52 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-12-20 12:26:05 +0000 |
commit | eebe65c18603638d221d4b7718675476de5d280c (patch) | |
tree | f669b1f66e2b46323cfb6d63fcca876519061b16 /bitbake/lib | |
parent | a4457cf939a524e467c9364b18bf2f71de163029 (diff) | |
download | poky-eebe65c18603638d221d4b7718675476de5d280c.tar.gz |
bitbake: runqueue: Further extend bitbake -S output to view signature differences
Based upon the list of difference starting points, we can use the siggen.find_siginfo()
function call and the difference printing code to provide a list of differences
between the current build target and whatever can be obtained from the sstate cache.
(Bitbake rev: 7a77861feb62750ef166d2d1e89ed1f444ca8dc7)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/bb/runqueue.py | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 37dc362008..457723603a 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
@@ -30,6 +30,7 @@ import stat | |||
30 | import fcntl | 30 | import fcntl |
31 | import errno | 31 | import errno |
32 | import logging | 32 | import logging |
33 | import re | ||
33 | import bb | 34 | import bb |
34 | from bb import msg, data, event | 35 | from bb import msg, data, event |
35 | from bb import monitordisk | 36 | from bb import monitordisk |
@@ -43,6 +44,8 @@ except ImportError: | |||
43 | bblogger = logging.getLogger("BitBake") | 44 | bblogger = logging.getLogger("BitBake") |
44 | logger = logging.getLogger("BitBake.RunQueue") | 45 | logger = logging.getLogger("BitBake.RunQueue") |
45 | 46 | ||
47 | __find_md5__ = re.compile( r'(?i)(?<![a-z0-9])[a-f0-9]{32}(?![a-z0-9])' ) | ||
48 | |||
46 | class RunQueueStats: | 49 | class RunQueueStats: |
47 | """ | 50 | """ |
48 | Holds statistics on the tasks handled by the associated runQueue | 51 | Holds statistics on the tasks handled by the associated runQueue |
@@ -1026,8 +1029,10 @@ class RunQueue: | |||
1026 | 1029 | ||
1027 | if self.state is runQueueSceneInit: | 1030 | if self.state is runQueueSceneInit: |
1028 | if self.cooker.configuration.dump_signatures: | 1031 | if self.cooker.configuration.dump_signatures: |
1029 | self.print_diffscenetasks() | 1032 | invalidtasks = self.print_diffscenetasks() |
1030 | self.dump_signatures() | 1033 | self.dump_signatures() |
1034 | self.write_diffscenetasks(invalidtasks) | ||
1035 | self.state = runQueueComplete | ||
1031 | else: | 1036 | else: |
1032 | self.start_worker() | 1037 | self.start_worker() |
1033 | self.rqexe = RunQueueExecuteScenequeue(self) | 1038 | self.rqexe = RunQueueExecuteScenequeue(self) |
@@ -1098,7 +1103,6 @@ class RunQueue: | |||
1098 | self.rqexe.finish() | 1103 | self.rqexe.finish() |
1099 | 1104 | ||
1100 | def dump_signatures(self): | 1105 | def dump_signatures(self): |
1101 | self.state = runQueueComplete | ||
1102 | done = set() | 1106 | done = set() |
1103 | bb.note("Reparsing files to collect dependency data") | 1107 | bb.note("Reparsing files to collect dependency data") |
1104 | for task in range(len(self.rqdata.runq_fnid)): | 1108 | for task in range(len(self.rqdata.runq_fnid)): |
@@ -1188,6 +1192,45 @@ class RunQueue: | |||
1188 | if tasklist: | 1192 | if tasklist: |
1189 | bb.plain("The differences between the current build and any cached tasks start at the following tasks:\n" + "\n".join(tasklist)) | 1193 | bb.plain("The differences between the current build and any cached tasks start at the following tasks:\n" + "\n".join(tasklist)) |
1190 | 1194 | ||
1195 | return invalidtasks.difference(found) | ||
1196 | |||
1197 | def write_diffscenetasks(self, invalidtasks): | ||
1198 | |||
1199 | # Define recursion callback | ||
1200 | def recursecb(key, hash1, hash2): | ||
1201 | hashes = [hash1, hash2] | ||
1202 | hashfiles = bb.siggen.find_siginfo(key, None, hashes, self.cfgData) | ||
1203 | |||
1204 | recout = [] | ||
1205 | if len(hashfiles) == 2: | ||
1206 | out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb) | ||
1207 | recout.extend(list(' ' + l for l in out2)) | ||
1208 | else: | ||
1209 | recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2)) | ||
1210 | |||
1211 | return recout | ||
1212 | |||
1213 | |||
1214 | for task in invalidtasks: | ||
1215 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] | ||
1216 | pn = self.rqdata.dataCache.pkg_fn[fn] | ||
1217 | taskname = self.rqdata.runq_task[task] | ||
1218 | h = self.rqdata.runq_hash[task] | ||
1219 | matches = bb.siggen.find_siginfo(pn, taskname, [], self.cfgData) | ||
1220 | match = None | ||
1221 | for m in matches: | ||
1222 | if h in m: | ||
1223 | match = m | ||
1224 | if match is None: | ||
1225 | bb.fatal("Can't find a task we're supposed to have written out? (hash: %s)?" % h) | ||
1226 | matches = {k : v for k, v in matches.iteritems() if h not in k} | ||
1227 | latestmatch = sorted(matches.keys(), key=lambda f: matches[f])[-1] | ||
1228 | prevh = __find_md5__.search(latestmatch).group(0) | ||
1229 | output = bb.siggen.compare_sigfiles(latestmatch, match, recursecb) | ||
1230 | bb.plain("\nTask %s:%s couldn't be used from the cache because:\n We need hash %s, closest matching task was %s\n " % (pn, taskname, h, prevh) + '\n '.join(output)) | ||
1231 | |||
1232 | |||
1233 | |||
1191 | class RunQueueExecute: | 1234 | class RunQueueExecute: |
1192 | 1235 | ||
1193 | def __init__(self, rq): | 1236 | def __init__(self, rq): |