diff options
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 95 |
1 files changed, 60 insertions, 35 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 4da543ffc8..2ef2670da0 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -5,20 +5,23 @@ | |||
| 5 | BitBake 'RunQueue' implementation | 5 | BitBake 'RunQueue' implementation |
| 6 | 6 | ||
| 7 | Handles preparation and execution of a queue of tasks | 7 | Handles preparation and execution of a queue of tasks |
| 8 | |||
| 9 | Copyright (C) 2006 Richard Purdie | ||
| 10 | |||
| 11 | This program is free software; you can redistribute it and/or modify it under | ||
| 12 | the terms of the GNU General Public License version 2 as published by the Free | ||
| 13 | Software Foundation | ||
| 14 | |||
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 17 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
| 18 | |||
| 19 | You should have received a copy of the GNU General Public License along with | ||
| 20 | """ | 8 | """ |
| 21 | 9 | ||
| 10 | # Copyright (C) 2006 Richard Purdie | ||
| 11 | # | ||
| 12 | # This program is free software; you can redistribute it and/or modify | ||
| 13 | # it under the terms of the GNU General Public License version 2 as | ||
| 14 | # published by the Free Software Foundation. | ||
| 15 | # | ||
| 16 | # This program is distributed in the hope that it will be useful, | ||
| 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | # GNU General Public License for more details. | ||
| 20 | # | ||
| 21 | # You should have received a copy of the GNU General Public License along | ||
| 22 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
| 23 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 24 | |||
| 22 | from bb import msg, data, fetch, event, mkdirhier, utils | 25 | from bb import msg, data, fetch, event, mkdirhier, utils |
| 23 | from sets import Set | 26 | from sets import Set |
| 24 | import bb, os, sys | 27 | import bb, os, sys |
| @@ -48,7 +51,7 @@ class RunQueue: | |||
| 48 | taskname = self.runq_task[task] | 51 | taskname = self.runq_task[task] |
| 49 | return "%s, %s" % (fn, taskname) | 52 | return "%s, %s" % (fn, taskname) |
| 50 | 53 | ||
| 51 | def prepare_runqueue(self, cfgData, dataCache, taskData, targets): | 54 | def prepare_runqueue(self, cooker, cfgData, dataCache, taskData, targets): |
| 52 | """ | 55 | """ |
| 53 | Turn a set of taskData into a RunQueue and compute data needed | 56 | Turn a set of taskData into a RunQueue and compute data needed |
| 54 | to optimise the execution order. | 57 | to optimise the execution order. |
| @@ -104,9 +107,13 @@ class RunQueue: | |||
| 104 | depdata = taskData.build_targets[depid][0] | 107 | depdata = taskData.build_targets[depid][0] |
| 105 | if depdata: | 108 | if depdata: |
| 106 | dep = taskData.fn_index[depdata] | 109 | dep = taskData.fn_index[depdata] |
| 107 | taskid = taskData.gettask_id(dep, taskname) | 110 | # Need to avoid creating new tasks here |
| 108 | depends.append(taskid) | 111 | taskid = taskData.gettask_id(dep, taskname, False) |
| 109 | fnid = taskData.tasks_fnid[taskid] | 112 | if taskid: |
| 113 | depends.append(taskid) | ||
| 114 | fnid = taskData.tasks_fnid[taskid] | ||
| 115 | else: | ||
| 116 | fnid = taskData.getfn_id(dep) | ||
| 110 | for nextdepid in taskData.depids[fnid]: | 117 | for nextdepid in taskData.depids[fnid]: |
| 111 | if nextdepid not in dep_seen: | 118 | if nextdepid not in dep_seen: |
| 112 | add_recursive_build(nextdepid) | 119 | add_recursive_build(nextdepid) |
| @@ -127,9 +134,13 @@ class RunQueue: | |||
| 127 | depdata = taskData.run_targets[rdepid][0] | 134 | depdata = taskData.run_targets[rdepid][0] |
| 128 | if depdata: | 135 | if depdata: |
| 129 | dep = taskData.fn_index[depdata] | 136 | dep = taskData.fn_index[depdata] |
| 130 | taskid = taskData.gettask_id(dep, taskname) | 137 | # Need to avoid creating new tasks here |
| 131 | depends.append(taskid) | 138 | taskid = taskData.gettask_id(dep, taskname, False) |
| 132 | fnid = taskData.tasks_fnid[taskid] | 139 | if taskid: |
| 140 | depends.append(taskid) | ||
| 141 | fnid = taskData.tasks_fnid[taskid] | ||
| 142 | else: | ||
| 143 | fnid = taskData.getfn_id(dep) | ||
| 133 | for nextdepid in taskData.depids[fnid]: | 144 | for nextdepid in taskData.depids[fnid]: |
| 134 | if nextdepid not in dep_seen: | 145 | if nextdepid not in dep_seen: |
| 135 | add_recursive_build(nextdepid) | 146 | add_recursive_build(nextdepid) |
| @@ -143,11 +154,11 @@ class RunQueue: | |||
| 143 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: | 154 | if 'recrdeptask' in task_deps and taskData.tasks_name[task] in task_deps['recrdeptask']: |
| 144 | dep_seen = [] | 155 | dep_seen = [] |
| 145 | rdep_seen = [] | 156 | rdep_seen = [] |
| 146 | taskname = task_deps['recrdeptask'][taskData.tasks_name[task]] | 157 | for taskname in task_deps['recrdeptask'][taskData.tasks_name[task]].split(): |
| 147 | for depid in taskData.depids[fnid]: | 158 | for depid in taskData.depids[fnid]: |
| 148 | add_recursive_build(depid) | 159 | add_recursive_build(depid) |
| 149 | for rdepid in taskData.rdepids[fnid]: | 160 | for rdepid in taskData.rdepids[fnid]: |
| 150 | add_recursive_run(rdepid) | 161 | add_recursive_run(rdepid) |
| 151 | 162 | ||
| 152 | #Prune self references | 163 | #Prune self references |
| 153 | if task in depends: | 164 | if task in depends: |
| @@ -188,13 +199,21 @@ class RunQueue: | |||
| 188 | 199 | ||
| 189 | for target in targets: | 200 | for target in targets: |
| 190 | targetid = taskData.getbuild_id(target[0]) | 201 | targetid = taskData.getbuild_id(target[0]) |
| 191 | if targetid in taskData.failed_deps: | ||
| 192 | continue | ||
| 193 | 202 | ||
| 194 | if targetid not in taskData.build_targets: | 203 | if targetid not in taskData.build_targets: |
| 195 | continue | 204 | continue |
| 196 | 205 | ||
| 197 | fnid = taskData.build_targets[targetid][0] | 206 | fnid = taskData.build_targets[targetid][0] |
| 207 | |||
| 208 | # Remove stamps for targets if force mode active | ||
| 209 | if cooker.configuration.force: | ||
| 210 | fn = taskData.fn_index[fnid] | ||
| 211 | bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (target[1], fn)) | ||
| 212 | bb.build.del_stamp(target[1], dataCache, fn) | ||
| 213 | |||
| 214 | if targetid in taskData.failed_deps: | ||
| 215 | continue | ||
| 216 | |||
| 198 | if fnid in taskData.failed_fnids: | 217 | if fnid in taskData.failed_fnids: |
| 199 | continue | 218 | continue |
| 200 | 219 | ||
| @@ -338,10 +357,13 @@ class RunQueue: | |||
| 338 | 357 | ||
| 339 | bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue") | 358 | bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue") |
| 340 | 359 | ||
| 360 | active_builds = 0 | ||
| 361 | tasks_completed = 0 | ||
| 362 | tasks_skipped = 0 | ||
| 363 | |||
| 341 | runq_buildable = [] | 364 | runq_buildable = [] |
| 342 | runq_running = [] | 365 | runq_running = [] |
| 343 | runq_complete = [] | 366 | runq_complete = [] |
| 344 | active_builds = 0 | ||
| 345 | build_pids = {} | 367 | build_pids = {} |
| 346 | failed_fnids = [] | 368 | failed_fnids = [] |
| 347 | 369 | ||
| @@ -405,15 +427,15 @@ class RunQueue: | |||
| 405 | fn = taskData.fn_index[self.runq_fnid[task]] | 427 | fn = taskData.fn_index[self.runq_fnid[task]] |
| 406 | taskname = self.runq_task[task] | 428 | taskname = self.runq_task[task] |
| 407 | 429 | ||
| 408 | if bb.build.stamp_is_current_cache(dataCache, fn, taskname): | 430 | if bb.build.stamp_is_current(taskname, dataCache, fn): |
| 409 | targetid = taskData.gettask_id(fn, taskname) | 431 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task, taskData))) |
| 410 | if not (targetid in taskData.external_targets and cooker.configuration.force): | 432 | runq_running[task] = 1 |
| 411 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task, taskData))) | 433 | task_complete(self, task) |
| 412 | runq_running[task] = 1 | 434 | tasks_completed = tasks_completed + 1 |
| 413 | task_complete(self, task) | 435 | tasks_skipped = tasks_skipped + 1 |
| 414 | continue | 436 | continue |
| 415 | 437 | ||
| 416 | bb.msg.debug(1, bb.msg.domain.RunQueue, "Running task %s (%s)" % (task, self.get_user_idstring(task, taskData))) | 438 | bb.msg.note(1, bb.msg.domain.RunQueue, "Running task %d of %d (ID: %s, %s)" % (tasks_completed + active_builds + 1, len(self.runq_fnid), task, self.get_user_idstring(task, taskData))) |
| 417 | try: | 439 | try: |
| 418 | pid = os.fork() | 440 | pid = os.fork() |
| 419 | except OSError, e: | 441 | except OSError, e: |
| @@ -451,6 +473,7 @@ class RunQueue: | |||
| 451 | failed_fnids.append(self.runq_fnid[task]) | 473 | failed_fnids.append(self.runq_fnid[task]) |
| 452 | break | 474 | break |
| 453 | task_complete(self, task) | 475 | task_complete(self, task) |
| 476 | tasks_completed = tasks_completed + 1 | ||
| 454 | del build_pids[result[0]] | 477 | del build_pids[result[0]] |
| 455 | continue | 478 | continue |
| 456 | break | 479 | break |
| @@ -486,6 +509,8 @@ class RunQueue: | |||
| 486 | if runq_complete[task] == 0: | 509 | if runq_complete[task] == 0: |
| 487 | bb.msg.error(bb.msg.domain.RunQueue, "Task %s never completed!" % task) | 510 | bb.msg.error(bb.msg.domain.RunQueue, "Task %s never completed!" % task) |
| 488 | 511 | ||
| 512 | bb.msg.note(1, bb.msg.domain.RunQueue, "Tasks Summary: Attempted %d tasks of which %d didn't need to be rerun and %d failed." % (tasks_completed, tasks_skipped, len(failed_fnids))) | ||
| 513 | |||
| 489 | return failed_fnids | 514 | return failed_fnids |
| 490 | 515 | ||
| 491 | def dump_data(self, taskQueue): | 516 | def dump_data(self, taskQueue): |
