diff options
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 100 |
1 files changed, 42 insertions, 58 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index c45287d035..e927afbb86 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -375,9 +375,7 @@ class RunQueueData: | |||
| 375 | """ | 375 | """ |
| 376 | 376 | ||
| 377 | runq_build = [] | 377 | runq_build = [] |
| 378 | recursive_tdepends = {} | 378 | recursivetasks = {} |
| 379 | runq_recrdepends = [] | ||
| 380 | tdepends_fnid = {} | ||
| 381 | 379 | ||
| 382 | taskData = self.taskData | 380 | taskData = self.taskData |
| 383 | 381 | ||
| @@ -423,9 +421,15 @@ class RunQueueData: | |||
| 423 | if taskid is not None: | 421 | if taskid is not None: |
| 424 | depends.add(taskid) | 422 | depends.add(taskid) |
| 425 | 423 | ||
| 424 | def add_resolved_dependencies(depids, tasknames, depends): | ||
| 425 | for depid in depids: | ||
| 426 | for taskname in tasknames: | ||
| 427 | taskid = taskData.gettask_id_fromfnid(depid, taskname) | ||
| 428 | if taskid is not None: | ||
| 429 | depends.add(taskid) | ||
| 430 | |||
| 426 | for task in xrange(len(taskData.tasks_name)): | 431 | for task in xrange(len(taskData.tasks_name)): |
| 427 | depends = set() | 432 | depends = set() |
| 428 | recrdepends = [] | ||
| 429 | fnid = taskData.tasks_fnid[task] | 433 | fnid = taskData.tasks_fnid[task] |
| 430 | fn = taskData.fn_index[fnid] | 434 | fn = taskData.fn_index[fnid] |
| 431 | task_deps = self.dataCache.task_deps[fn] | 435 | task_deps = self.dataCache.task_deps[fn] |
| @@ -459,8 +463,6 @@ class RunQueueData: | |||
| 459 | # | 463 | # |
| 460 | # e.g. do_sometask[depends] = "targetname:do_someothertask" | 464 | # e.g. do_sometask[depends] = "targetname:do_someothertask" |
| 461 | # (makes sure sometask runs after targetname's someothertask) | 465 | # (makes sure sometask runs after targetname's someothertask) |
| 462 | if fnid not in tdepends_fnid: | ||
| 463 | tdepends_fnid[fnid] = set() | ||
| 464 | idepends = taskData.tasks_idepends[task] | 466 | idepends = taskData.tasks_idepends[task] |
| 465 | for (depid, idependtask) in idepends: | 467 | for (depid, idependtask) in idepends: |
| 466 | if depid in taskData.build_targets: | 468 | if depid in taskData.build_targets: |
| @@ -471,8 +473,6 @@ class RunQueueData: | |||
| 471 | if taskid is None: | 473 | if taskid is None: |
| 472 | bb.msg.fatal("RunQueue", "Task %s in %s depends upon non-existent task %s in %s" % (taskData.tasks_name[task], fn, idependtask, dep)) | 474 | bb.msg.fatal("RunQueue", "Task %s in %s depends upon non-existent task %s in %s" % (taskData.tasks_name[task], fn, idependtask, dep)) |
| 473 | depends.add(taskid) | 475 | depends.add(taskid) |
| 474 | if depdata != fnid: | ||
| 475 | tdepends_fnid[fnid].add(taskid) | ||
| 476 | irdepends = taskData.tasks_irdepends[task] | 476 | irdepends = taskData.tasks_irdepends[task] |
| 477 | for (depid, idependtask) in irdepends: | 477 | for (depid, idependtask) in irdepends: |
| 478 | if depid in taskData.run_targets: | 478 | if depid in taskData.run_targets: |
| @@ -483,24 +483,17 @@ class RunQueueData: | |||
| 483 | if taskid is None: | 483 | if taskid is None: |
| 484 | bb.msg.fatal("RunQueue", "Task %s in %s rdepends upon non-existent task %s in %s" % (taskData.tasks_name[task], fn, idependtask, dep)) | 484 | bb.msg.fatal("RunQueue", "Task %s in %s rdepends upon non-existent task %s in %s" % (taskData.tasks_name[task], fn, idependtask, dep)) |
| 485 | depends.add(taskid) | 485 | depends.add(taskid) |
| 486 | if depdata != fnid: | ||
| 487 | tdepends_fnid[fnid].add(taskid) | ||
| 488 | 486 | ||
| 489 | # Resolve recursive 'recrdeptask' dependencies (A) | 487 | # Resolve recursive 'recrdeptask' dependencies (Part A) |
| 490 | # | 488 | # |
| 491 | # e.g. do_sometask[recrdeptask] = "do_someothertask" | 489 | # e.g. do_sometask[recrdeptask] = "do_someothertask" |
| 492 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) | 490 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) |
| 493 | # We cover the recursive part of the dependencies below | 491 | # We cover the recursive part of the dependencies below |
| 494 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: | 492 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: |
| 495 | for taskname in task_deps['recrdeptask'][taskData.tasks_name[task]].split(): | 493 | tasknames = task_deps['recrdeptask'][taskData.tasks_name[task]].split() |
| 496 | recrdepends.append(taskname) | 494 | recursivetasks[task] = tasknames |
| 497 | add_build_dependencies(taskData.depids[fnid], [taskname], depends) | 495 | add_build_dependencies(taskData.depids[fnid], tasknames, depends) |
| 498 | add_runtime_dependencies(taskData.rdepids[fnid], [taskname], depends) | 496 | add_runtime_dependencies(taskData.rdepids[fnid], tasknames, depends) |
| 499 | |||
| 500 | # Rmove all self references | ||
| 501 | if task in depends: | ||
| 502 | logger.debug(2, "Task %s (%s %s) contains self reference! %s", task, taskData.fn_index[taskData.tasks_fnid[task]], taskData.tasks_name[task], depends) | ||
| 503 | depends.remove(task) | ||
| 504 | 497 | ||
| 505 | self.runq_fnid.append(taskData.tasks_fnid[task]) | 498 | self.runq_fnid.append(taskData.tasks_fnid[task]) |
| 506 | self.runq_task.append(taskData.tasks_name[task]) | 499 | self.runq_task.append(taskData.tasks_name[task]) |
| @@ -509,48 +502,39 @@ class RunQueueData: | |||
| 509 | self.runq_hash.append("") | 502 | self.runq_hash.append("") |
| 510 | 503 | ||
| 511 | runq_build.append(0) | 504 | runq_build.append(0) |
| 512 | runq_recrdepends.append(recrdepends) | ||
| 513 | 505 | ||
| 514 | # | 506 | # Resolve recursive 'recrdeptask' dependencies (Part B) |
| 515 | # Build a list of recursive cumulative dependencies for each fnid | ||
| 516 | # We do this by fnid, since if A depends on some task in B | ||
| 517 | # we're interested in later tasks B's fnid might have but B itself | ||
| 518 | # doesn't depend on | ||
| 519 | # | ||
| 520 | # Algorithm is O(tasks) + O(tasks)*O(fnids) | ||
| 521 | # | ||
| 522 | reccumdepends = {} | ||
| 523 | for task in xrange(len(self.runq_fnid)): | ||
| 524 | fnid = self.runq_fnid[task] | ||
| 525 | if fnid not in reccumdepends: | ||
| 526 | if fnid in tdepends_fnid: | ||
| 527 | reccumdepends[fnid] = tdepends_fnid[fnid] | ||
| 528 | else: | ||
| 529 | reccumdepends[fnid] = set() | ||
| 530 | reccumdepends[fnid].update(self.runq_depends[task]) | ||
| 531 | for task in xrange(len(self.runq_fnid)): | ||
| 532 | taskfnid = self.runq_fnid[task] | ||
| 533 | for fnid in reccumdepends: | ||
| 534 | if task in reccumdepends[fnid]: | ||
| 535 | reccumdepends[fnid].add(task) | ||
| 536 | if taskfnid in reccumdepends: | ||
| 537 | reccumdepends[fnid].update(reccumdepends[taskfnid]) | ||
| 538 | |||
| 539 | |||
| 540 | # Resolve recursive 'recrdeptask' dependencies (B) | ||
| 541 | # | 507 | # |
| 542 | # e.g. do_sometask[recrdeptask] = "do_someothertask" | 508 | # e.g. do_sometask[recrdeptask] = "do_someothertask" |
| 543 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) | 509 | # (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively) |
| 544 | for task in xrange(len(self.runq_fnid)): | 510 | # We need to do this separately since we need all of self.runq_depends to be complete before this is processed |
| 545 | if len(runq_recrdepends[task]) > 0: | 511 | extradeps = {} |
| 546 | taskfnid = self.runq_fnid[task] | 512 | for task in recursivetasks: |
| 547 | for dep in reccumdepends[taskfnid]: | 513 | extradeps[task] = set() |
| 548 | # Ignore self references | 514 | tasknames = recursivetasks[task] |
| 549 | if dep == task: | 515 | seendeps = set() |
| 550 | continue | 516 | seenfnid = [] |
| 551 | for taskname in runq_recrdepends[task]: | 517 | |
| 552 | if taskData.tasks_name[dep] == taskname: | 518 | def generate_recdeps(t): |
| 553 | self.runq_depends[task].add(dep) | 519 | newdeps = set() |
| 520 | add_resolved_dependencies([taskData.tasks_fnid[t]], tasknames, newdeps) | ||
| 521 | extradeps[task].update(newdeps) | ||
| 522 | seendeps.add(t) | ||
| 523 | newdeps.add(t) | ||
| 524 | for i in newdeps: | ||
| 525 | for n in self.runq_depends[i]: | ||
| 526 | if n not in seendeps: | ||
| 527 | generate_recdeps(n) | ||
| 528 | generate_recdeps(task) | ||
| 529 | |||
| 530 | for task in xrange(len(taskData.tasks_name)): | ||
| 531 | # Add in extra dependencies | ||
| 532 | if task in extradeps: | ||
| 533 | self.runq_depends[task].update(extradeps[task]) | ||
| 534 | # Remove all self references | ||
| 535 | if task in self.runq_depends[task]: | ||
| 536 | logger.debug(2, "Task %s (%s %s) contains self reference! %s", task, taskData.fn_index[taskData.tasks_fnid[task]], taskData.tasks_name[task], self.runq_depends[task]) | ||
| 537 | self.runq_depends[task].remove(task) | ||
| 554 | 538 | ||
| 555 | # Step B - Mark all active tasks | 539 | # Step B - Mark all active tasks |
| 556 | # | 540 | # |
