summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/runqueue.py83
1 files changed, 72 insertions, 11 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 75797e2520..0c7dfec2b6 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -785,6 +785,7 @@ class RunQueue:
785 self.stamppolicy = cfgData.getVar("BB_STAMP_POLICY", True) or "perfile" 785 self.stamppolicy = cfgData.getVar("BB_STAMP_POLICY", True) or "perfile"
786 self.hashvalidate = cfgData.getVar("BB_HASHCHECK_FUNCTION", True) or None 786 self.hashvalidate = cfgData.getVar("BB_HASHCHECK_FUNCTION", True) or None
787 self.setsceneverify = cfgData.getVar("BB_SETSCENE_VERIFY_FUNCTION", True) or None 787 self.setsceneverify = cfgData.getVar("BB_SETSCENE_VERIFY_FUNCTION", True) or None
788 self.depvalidate = cfgData.getVar("BB_SETSCENE_DEPVALID", True) or None
788 789
789 self.state = runQueuePrepare 790 self.state = runQueuePrepare
790 791
@@ -1161,6 +1162,26 @@ class RunQueueExecute:
1161 1162
1162 return pid, pipein, pipeout 1163 return pid, pipein, pipeout
1163 1164
1165 def check_dependencies(self, task, taskdeps, setscene = False):
1166 if not self.rq.depvalidate:
1167 return False
1168
1169 taskdata = {}
1170 taskdeps.add(task)
1171 for dep in taskdeps:
1172 if setscene:
1173 depid = self.rqdata.runq_setscene[dep]
1174 else:
1175 depid = dep
1176 fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[depid]]
1177 pn = self.rqdata.dataCache.pkg_fn[fn]
1178 taskname = self.rqdata.runq_task[depid]
1179 taskdata[dep] = [pn, taskname, fn]
1180 call = self.rq.depvalidate + "(task, taskdata, notneeded, d)"
1181 locs = { "task" : task, "taskdata" : taskdata, "notneeded" : self.scenequeue_notneeded, "d" : self.cooker.configuration.data }
1182 valid = bb.utils.better_eval(call, locs)
1183 return valid
1184
1164class RunQueueExecuteDummy(RunQueueExecute): 1185class RunQueueExecuteDummy(RunQueueExecute):
1165 def __init__(self, rq): 1186 def __init__(self, rq):
1166 self.rq = rq 1187 self.rq = rq
@@ -1198,16 +1219,8 @@ class RunQueueExecuteTasks(RunQueueExecute):
1198 logger.debug(1, 'Considering %s (%s): %s' % (task, self.rqdata.get_user_idstring(task), str(self.rqdata.runq_revdeps[task]))) 1219 logger.debug(1, 'Considering %s (%s): %s' % (task, self.rqdata.get_user_idstring(task), str(self.rqdata.runq_revdeps[task])))
1199 1220
1200 if len(self.rqdata.runq_revdeps[task]) > 0 and self.rqdata.runq_revdeps[task].issubset(self.rq.scenequeue_covered) and task not in self.rq.scenequeue_notcovered: 1221 if len(self.rqdata.runq_revdeps[task]) > 0 and self.rqdata.runq_revdeps[task].issubset(self.rq.scenequeue_covered) and task not in self.rq.scenequeue_notcovered:
1201 ok = True 1222 found = True
1202 for revdep in self.rqdata.runq_revdeps[task]: 1223 self.rq.scenequeue_covered.add(task)
1203 if self.rqdata.runq_fnid[task] != self.rqdata.runq_fnid[revdep]:
1204 logger.debug(1, 'Found "bad" dep %s (%s) for %s (%s)' % (revdep, self.rqdata.get_user_idstring(revdep), task, self.rqdata.get_user_idstring(task)))
1205
1206 ok = False
1207 break
1208 if ok:
1209 found = True
1210 self.rq.scenequeue_covered.add(task)
1211 1224
1212 logger.debug(1, 'Skip list (pre setsceneverify) %s', sorted(self.rq.scenequeue_covered)) 1225 logger.debug(1, 'Skip list (pre setsceneverify) %s', sorted(self.rq.scenequeue_covered))
1213 1226
@@ -1408,6 +1421,7 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1408 1421
1409 self.scenequeue_covered = set() 1422 self.scenequeue_covered = set()
1410 self.scenequeue_notcovered = set() 1423 self.scenequeue_notcovered = set()
1424 self.scenequeue_notneeded = set()
1411 1425
1412 # If we don't have any setscene functions, skip this step 1426 # If we don't have any setscene functions, skip this step
1413 if len(self.rqdata.runq_setscene) == 0: 1427 if len(self.rqdata.runq_setscene) == 0:
@@ -1417,7 +1431,6 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1417 1431
1418 self.stats = RunQueueStats(len(self.rqdata.runq_setscene)) 1432 self.stats = RunQueueStats(len(self.rqdata.runq_setscene))
1419 1433
1420 endpoints = {}
1421 sq_revdeps = [] 1434 sq_revdeps = []
1422 sq_revdeps_new = [] 1435 sq_revdeps_new = []
1423 sq_revdeps_squash = [] 1436 sq_revdeps_squash = []
@@ -1432,12 +1445,15 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1432 self.runq_complete.append(0) 1445 self.runq_complete.append(0)
1433 self.runq_buildable.append(0) 1446 self.runq_buildable.append(0)
1434 1447
1448 # First process the chains up to the first setscene task.
1449 endpoints = {}
1435 for task in xrange(len(self.rqdata.runq_fnid)): 1450 for task in xrange(len(self.rqdata.runq_fnid)):
1436 sq_revdeps.append(copy.copy(self.rqdata.runq_revdeps[task])) 1451 sq_revdeps.append(copy.copy(self.rqdata.runq_revdeps[task]))
1437 sq_revdeps_new.append(set()) 1452 sq_revdeps_new.append(set())
1438 if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene: 1453 if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene:
1439 endpoints[task] = set() 1454 endpoints[task] = set()
1440 1455
1456 # Secondly process the chains between setscene tasks.
1441 for task in self.rqdata.runq_setscene: 1457 for task in self.rqdata.runq_setscene:
1442 for dep in self.rqdata.runq_depends[task]: 1458 for dep in self.rqdata.runq_depends[task]:
1443 if dep not in endpoints: 1459 if dep not in endpoints:
@@ -1453,6 +1469,8 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1453 if sq_revdeps_new[point]: 1469 if sq_revdeps_new[point]:
1454 tasks |= sq_revdeps_new[point] 1470 tasks |= sq_revdeps_new[point]
1455 sq_revdeps_new[point] = set() 1471 sq_revdeps_new[point] = set()
1472 if point in self.rqdata.runq_setscene:
1473 sq_revdeps_new[point] = tasks
1456 for dep in self.rqdata.runq_depends[point]: 1474 for dep in self.rqdata.runq_depends[point]:
1457 if point in sq_revdeps[dep]: 1475 if point in sq_revdeps[dep]:
1458 sq_revdeps[dep].remove(point) 1476 sq_revdeps[dep].remove(point)
@@ -1465,6 +1483,42 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1465 1483
1466 process_endpoints(endpoints) 1484 process_endpoints(endpoints)
1467 1485
1486 # Build a list of setscene tasks which as "unskippable"
1487 # These are direct endpoints referenced by the build
1488 endpoints2 = {}
1489 sq_revdeps2 = []
1490 sq_revdeps_new2 = []
1491 def process_endpoints2(endpoints):
1492 newendpoints = {}
1493 for point, task in endpoints.items():
1494 tasks = set([point])
1495 if task:
1496 tasks |= task
1497 if sq_revdeps_new2[point]:
1498 tasks |= sq_revdeps_new2[point]
1499 sq_revdeps_new2[point] = set()
1500 if point in self.rqdata.runq_setscene:
1501 sq_revdeps_new2[point] = tasks
1502 for dep in self.rqdata.runq_depends[point]:
1503 if point in sq_revdeps2[dep]:
1504 sq_revdeps2[dep].remove(point)
1505 if tasks:
1506 sq_revdeps_new2[dep] |= tasks
1507 if (len(sq_revdeps2[dep]) == 0 or len(sq_revdeps_new2[dep]) != 0) and dep not in self.rqdata.runq_setscene:
1508 newendpoints[dep] = tasks
1509 if len(newendpoints) != 0:
1510 process_endpoints2(newendpoints)
1511 for task in xrange(len(self.rqdata.runq_fnid)):
1512 sq_revdeps2.append(copy.copy(self.rqdata.runq_revdeps[task]))
1513 sq_revdeps_new2.append(set())
1514 if (len(self.rqdata.runq_revdeps[task]) == 0) and task not in self.rqdata.runq_setscene:
1515 endpoints2[task] = set()
1516 process_endpoints2(endpoints2)
1517 self.unskippable = []
1518 for task in self.rqdata.runq_setscene:
1519 if sq_revdeps_new2[task]:
1520 self.unskippable.append(self.rqdata.runq_setscene.index(task))
1521
1468 for task in xrange(len(self.rqdata.runq_fnid)): 1522 for task in xrange(len(self.rqdata.runq_fnid)):
1469 if task in self.rqdata.runq_setscene: 1523 if task in self.rqdata.runq_setscene:
1470 deps = set() 1524 deps = set()
@@ -1625,6 +1679,13 @@ class RunQueueExecuteScenequeue(RunQueueExecute):
1625 # Find the next setscene to run 1679 # Find the next setscene to run
1626 for nexttask in xrange(self.stats.total): 1680 for nexttask in xrange(self.stats.total):
1627 if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1: 1681 if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1:
1682 if nexttask in self.unskippable:
1683 logger.debug(2, "Setscene task %s is unskippable" % self.rqdata.get_user_idstring(self.rqdata.runq_setscene[nexttask]))
1684 if nexttask not in self.unskippable and len(self.sq_revdeps[nexttask]) > 0 and self.sq_revdeps[nexttask].issubset(self.scenequeue_covered) and self.check_dependencies(nexttask, self.sq_revdeps[nexttask], True):
1685 logger.debug(2, "Skipping setscene for task %s" % self.rqdata.get_user_idstring(self.rqdata.runq_setscene[nexttask]))
1686 self.task_skip(nexttask)
1687 self.scenequeue_notneeded.add(nexttask)
1688 return True
1628 task = nexttask 1689 task = nexttask
1629 break 1690 break
1630 if task is not None: 1691 if task is not None: