@@ -235,23 +235,50 @@ def sstate_log_expand_paths(d, message):
python sstate_save_task_log () {
import json
- # Save the messages logged by this task, so they can be replayed when the
- # task is restored from sstate. The records are written by bitbake right
- # after the task body, before the postfuncs.
+ # Also bundle the messages of the non-sstate tasks of this recipe we depend
+ # on, as they are skipped when this task is restored from sstate. bitbake
+ # picks which setscene task replays them (BB_SETSCENE_REPLAY_TASKS).
+ taskdepdata = d.getVar('BB_TASKDEPDATA', False) or {}
+ sstatetasks = d.getVar('SSTATETASKS').split()
mytask = d.getVar('BB_RUNTASK')
- recordsfn = os.path.join(d.getVar('T'), 'logrecords.%s.json' % mytask)
- if not os.path.exists(recordsfn):
- return
- with open(recordsfn) as f:
- records = json.load(f)
-
- tasks = {mytask: [{'levelno': levelno,
- 'message': sstate_log_strip_paths(d, message)}
- for levelno, message in records]}
-
- logfn = os.path.join(d.getVar('SSTATE_BUILDDIR'), "sstate-log.json")
- with open(logfn, 'w') as f:
- json.dump({'tasks': tasks}, f)
+ # The running task is always an entry in taskdepdata, under its own tid.
+ # Reconstruct that tid from BB_FILENAME and BB_RUNTASK.
+ filename = d.getVar('BB_FILENAME', False)
+ start = filename + ":" + mytask if filename else None
+ if start not in taskdepdata:
+ bb.fatal("sstate: cannot identify task %s in taskdepdata" % start)
+
+ loggedtasks = {mytask}
+ seen = {start}
+ todo = [start]
+ while todo:
+ for dep in taskdepdata[todo.pop()].deps:
+ t = taskdepdata[dep]
+ if dep in seen or t.fn != taskdepdata[start].fn or t.taskname in sstatetasks:
+ continue
+ seen.add(dep)
+ todo.append(dep)
+ loggedtasks.add(t.taskname)
+
+ # Every task writes its records to ${T} right after its body, before its
+ # postfuncs, so our own file and the dependency files all exist by now.
+ tasklogs = {}
+ for taskname in loggedtasks:
+ recordsfn = os.path.join(d.getVar('T'), 'logrecords.%s.json' % taskname)
+ if os.path.exists(recordsfn):
+ with open(recordsfn) as f:
+ tasklogs[taskname] = json.load(f)
+
+ tasks = {}
+ for task, records in tasklogs.items():
+ tasks[task] = [{'levelno': levelno,
+ 'message': sstate_log_strip_paths(d, message)}
+ for levelno, message in records]
+
+ if tasks:
+ logfn = os.path.join(d.getVar('SSTATE_BUILDDIR'), "sstate-log.json")
+ with open(logfn, 'w') as f:
+ json.dump({'tasks': tasks}, f)
}
def sstate_add(ss, source, dest, d):
@@ -462,7 +489,11 @@ def sstate_installpkgdir(ss, d, replay=False):
if os.path.exists(logfp):
with open(logfp, 'r') as logfile:
logdata = json.load(logfile)
- records = logdata.get('tasks', {}).get(d.getVar('BB_RUNTASK').removesuffix('_setscene'), [])
+ replaytasks = (d.getVar('BB_SETSCENE_REPLAY_TASKS') or '').split()
+ replaytasks.append(d.getVar('BB_RUNTASK').removesuffix('_setscene'))
+ records = []
+ for task in replaytasks:
+ records += logdata.get('tasks', {}).get(task, [])
for logentry in records:
levelno = logentry.get('levelno', 0)
if levelno < bb.msg.BBLogFormatter.WARNONCE or "message" not in logentry:
@@ -481,6 +512,8 @@ def sstate_installpkgdir(ss, d, replay=False):
return True
+sstate_installpkgdir[vardepsexclude] += "BB_SETSCENE_REPLAY_TASKS"
+
python sstate_hardcode_path_unpack () {
# Fixup hardcoded paths
#
Tasks which are not sstate tasks (do_configure, do_compile, do_install) are skipped when covered by a setscene task, so their messages were never shown again on sstate reuse. When creating an sstate package, also bundle the records of the same-recipe non-sstate tasks this task depends on, read from ${T}/logrecords.<task>.json. On install, replay the records of the covered tasks bitbake assigned to this setscene task through BB_SETSCENE_REPLAY_TASKS, so each covered task is replayed exactly once even when several setscene tasks cover it. AI-Generated: Uses opencode (DeepSeek V4 Flash) Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> --- meta/classes-global/sstate.bbclass | 67 ++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 17 deletions(-)