diff options
| author | Richard Purdie <richard@openedhand.com> | 2008-03-14 11:44:34 +0000 | 
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2008-03-14 11:44:34 +0000 | 
| commit | 853280f161ed24f9b976a6f53739c08ac2362ddb (patch) | |
| tree | ae67e05e66c92dd3fc668b1976084a628bc99882 | |
| parent | 097076da2349e638342e69e465c85683adb6ccc7 (diff) | |
| download | poky-853280f161ed24f9b976a6f53739c08ac2362ddb.tar.gz | |
bitbake: Update with changes from bitbake 1.8 branch
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@4006 311d38ba-8fff-0310-9ca6-ca027cbcb966
| -rw-r--r-- | bitbake/ChangeLog | 5 | ||||
| -rw-r--r-- | bitbake/lib/bb/cache.py | 78 | ||||
| -rw-r--r-- | bitbake/lib/bb/cooker.py | 7 | ||||
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 130 | ||||
| -rw-r--r-- | bitbake/lib/bb/taskdata.py | 14 | 
5 files changed, 152 insertions, 82 deletions
diff --git a/bitbake/ChangeLog b/bitbake/ChangeLog index d074a5e239..7bed88112e 100644 --- a/bitbake/ChangeLog +++ b/bitbake/ChangeLog  | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | Changes in BitBake 1.8.x: | 1 | Changes in BitBake 1.8.x: | 
| 2 | - Fix -f (force) in conjunction with -b | ||
| 2 | - Fix exit code for build failures in --continue mode | 3 | - Fix exit code for build failures in --continue mode | 
| 3 | - Fix git branch tags fetching | 4 | - Fix git branch tags fetching | 
| 4 | - Change parseConfigurationFile so it works on real data, not a copy | 5 | - Change parseConfigurationFile so it works on real data, not a copy | 
| @@ -21,6 +22,10 @@ Changes in BitBake 1.8.x: | |||
| 21 | the way bitbake schedules tasks | 22 | the way bitbake schedules tasks | 
| 22 | - Add BB_STAMP_POLICY variable/option ("perfile" or "full") controlling | 23 | - Add BB_STAMP_POLICY variable/option ("perfile" or "full") controlling | 
| 23 | how extensively stamps are looked at for validity | 24 | how extensively stamps are looked at for validity | 
| 25 | - When handling build target failures make sure idepends are checked and | ||
| 26 | failed where needed. Fixes --continue mode crashes. | ||
| 27 | - Fix problems with recrdeptask handling where some idepends weren't handled | ||
| 28 | correctly. | ||
| 24 | 29 | ||
| 25 | Changes in BitBake 1.8.10: | 30 | Changes in BitBake 1.8.10: | 
| 26 | - Psyco is available only for x86 - do not use it on other architectures. | 31 | - Psyco is available only for x86 - do not use it on other architectures. | 
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py index 60e863d52d..9acd301f52 100644 --- a/bitbake/lib/bb/cache.py +++ b/bitbake/lib/bb/cache.py  | |||
| @@ -80,7 +80,7 @@ class Cache: | |||
| 80 | if old_mtime > newest_mtime: | 80 | if old_mtime > newest_mtime: | 
| 81 | newest_mtime = old_mtime | 81 | newest_mtime = old_mtime | 
| 82 | 82 | ||
| 83 | if self.mtime(self.cachefile) >= newest_mtime: | 83 | if bb.parse.cached_mtime_noerror(self.cachefile) >= newest_mtime: | 
| 84 | try: | 84 | try: | 
| 85 | p = pickle.Unpickler(file(self.cachefile, "rb")) | 85 | p = pickle.Unpickler(file(self.cachefile, "rb")) | 
| 86 | self.depends_cache, version_data = p.load() | 86 | self.depends_cache, version_data = p.load() | 
| @@ -91,7 +91,7 @@ class Cache: | |||
| 91 | except EOFError: | 91 | except EOFError: | 
| 92 | bb.msg.note(1, bb.msg.domain.Cache, "Truncated cache found, rebuilding...") | 92 | bb.msg.note(1, bb.msg.domain.Cache, "Truncated cache found, rebuilding...") | 
| 93 | self.depends_cache = {} | 93 | self.depends_cache = {} | 
| 94 | except (ValueError, KeyError): | 94 | except: | 
| 95 | bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...") | 95 | bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...") | 
| 96 | self.depends_cache = {} | 96 | self.depends_cache = {} | 
| 97 | else: | 97 | else: | 
| @@ -199,31 +199,34 @@ class Cache: | |||
| 199 | self.remove(fn) | 199 | self.remove(fn) | 
| 200 | return False | 200 | return False | 
| 201 | 201 | ||
| 202 | mtime = bb.parse.cached_mtime_noerror(fn) | ||
| 203 | |||
| 202 | # Check file still exists | 204 | # Check file still exists | 
| 203 | if self.mtime(fn) == 0: | 205 | if mtime == 0: | 
| 204 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn) | 206 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn) | 
| 205 | self.remove(fn) | 207 | self.remove(fn) | 
| 206 | return False | 208 | return False | 
| 207 | 209 | ||
| 208 | # Check the file's timestamp | 210 | # Check the file's timestamp | 
| 209 | if bb.parse.cached_mtime(fn) > self.getVar("CACHETIMESTAMP", fn, True): | 211 | if mtime > self.getVar("CACHETIMESTAMP", fn, True): | 
| 210 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn) | 212 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn) | 
| 211 | self.remove(fn) | 213 | self.remove(fn) | 
| 212 | return False | 214 | return False | 
| 213 | 215 | ||
| 214 | # Check dependencies are still valid | 216 | # Check dependencies are still valid | 
| 215 | depends = self.getVar("__depends", fn, True) | 217 | depends = self.getVar("__depends", fn, True) | 
| 216 | for f,old_mtime in depends: | 218 | if depends: | 
| 217 | # Check if file still exists | 219 | for f,old_mtime in depends: | 
| 218 | if self.mtime(f) == 0: | 220 | fmtime = bb.parse.cached_mtime_noerror(f) | 
| 219 | self.remove(fn) | 221 | # Check if file still exists | 
| 220 | return False | 222 | if fmtime == 0: | 
| 221 | 223 | self.remove(fn) | |
| 222 | new_mtime = bb.parse.cached_mtime(f) | 224 | return False | 
| 223 | if (new_mtime > old_mtime): | 225 | |
| 224 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s's dependency %s changed" % (fn, f)) | 226 | if (fmtime > old_mtime): | 
| 225 | self.remove(fn) | 227 | bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s's dependency %s changed" % (fn, f)) | 
| 226 | return False | 228 | self.remove(fn) | 
| 229 | return False | ||
| 227 | 230 | ||
| 228 | #bb.msg.debug(2, bb.msg.domain.Cache, "Depends Cache: %s is clean" % fn) | 231 | #bb.msg.debug(2, bb.msg.domain.Cache, "Depends Cache: %s is clean" % fn) | 
| 229 | if not fn in self.clean: | 232 | if not fn in self.clean: | 
| @@ -284,7 +287,6 @@ class Cache: | |||
| 284 | pv = self.getVar('PV', file_name, True) | 287 | pv = self.getVar('PV', file_name, True) | 
| 285 | pr = self.getVar('PR', file_name, True) | 288 | pr = self.getVar('PR', file_name, True) | 
| 286 | dp = int(self.getVar('DEFAULT_PREFERENCE', file_name, True) or "0") | 289 | dp = int(self.getVar('DEFAULT_PREFERENCE', file_name, True) or "0") | 
| 287 | provides = Set([pn] + (self.getVar("PROVIDES", file_name, True) or "").split()) | ||
| 288 | depends = bb.utils.explode_deps(self.getVar("DEPENDS", file_name, True) or "") | 290 | depends = bb.utils.explode_deps(self.getVar("DEPENDS", file_name, True) or "") | 
| 289 | packages = (self.getVar('PACKAGES', file_name, True) or "").split() | 291 | packages = (self.getVar('PACKAGES', file_name, True) or "").split() | 
| 290 | packages_dynamic = (self.getVar('PACKAGES_DYNAMIC', file_name, True) or "").split() | 292 | packages_dynamic = (self.getVar('PACKAGES_DYNAMIC', file_name, True) or "").split() | 
| @@ -304,24 +306,31 @@ class Cache: | |||
| 304 | cacheData.pkg_pepvpr[file_name] = (pe,pv,pr) | 306 | cacheData.pkg_pepvpr[file_name] = (pe,pv,pr) | 
| 305 | cacheData.pkg_dp[file_name] = dp | 307 | cacheData.pkg_dp[file_name] = dp | 
| 306 | 308 | ||
| 309 | provides = [pn] | ||
| 310 | for provide in (self.getVar("PROVIDES", file_name, True) or "").split(): | ||
| 311 | if provide not in provides: | ||
| 312 | provides.append(provide) | ||
| 313 | |||
| 307 | # Build forward and reverse provider hashes | 314 | # Build forward and reverse provider hashes | 
| 308 | # Forward: virtual -> [filenames] | 315 | # Forward: virtual -> [filenames] | 
| 309 | # Reverse: PN -> [virtuals] | 316 | # Reverse: PN -> [virtuals] | 
| 310 | if pn not in cacheData.pn_provides: | 317 | if pn not in cacheData.pn_provides: | 
| 311 | cacheData.pn_provides[pn] = Set() | 318 | cacheData.pn_provides[pn] = [] | 
| 312 | cacheData.pn_provides[pn] |= provides | ||
| 313 | 319 | ||
| 314 | cacheData.fn_provides[file_name] = Set() | 320 | cacheData.fn_provides[file_name] = provides | 
| 315 | for provide in provides: | 321 | for provide in provides: | 
| 316 | if provide not in cacheData.providers: | 322 | if provide not in cacheData.providers: | 
| 317 | cacheData.providers[provide] = [] | 323 | cacheData.providers[provide] = [] | 
| 318 | cacheData.providers[provide].append(file_name) | 324 | cacheData.providers[provide].append(file_name) | 
| 319 | cacheData.fn_provides[file_name].add(provide) | 325 | if not provide in cacheData.pn_provides[pn]: | 
| 326 | cacheData.pn_provides[pn].append(provide) | ||
| 320 | 327 | ||
| 321 | cacheData.deps[file_name] = Set() | 328 | cacheData.deps[file_name] = [] | 
| 322 | for dep in depends: | 329 | for dep in depends: | 
| 323 | cacheData.all_depends.add(dep) | 330 | if not dep in cacheData.deps[file_name]: | 
| 324 | cacheData.deps[file_name].add(dep) | 331 | cacheData.deps[file_name].append(dep) | 
| 332 | if not dep in cacheData.all_depends: | ||
| 333 | cacheData.all_depends.append(dep) | ||
| 325 | 334 | ||
| 326 | # Build reverse hash for PACKAGES, so runtime dependencies | 335 | # Build reverse hash for PACKAGES, so runtime dependencies | 
| 327 | # can be be resolved (RDEPENDS, RRECOMMENDS etc.) | 336 | # can be be resolved (RDEPENDS, RRECOMMENDS etc.) | 
| @@ -343,28 +352,21 @@ class Cache: | |||
| 343 | 352 | ||
| 344 | # Build hash of runtime depends and rececommends | 353 | # Build hash of runtime depends and rececommends | 
| 345 | 354 | ||
| 346 | def add_dep(deplist, deps): | ||
| 347 | for dep in deps: | ||
| 348 | if not dep in deplist: | ||
| 349 | deplist[dep] = "" | ||
| 350 | |||
| 351 | if not file_name in cacheData.rundeps: | 355 | if not file_name in cacheData.rundeps: | 
| 352 | cacheData.rundeps[file_name] = {} | 356 | cacheData.rundeps[file_name] = {} | 
| 353 | if not file_name in cacheData.runrecs: | 357 | if not file_name in cacheData.runrecs: | 
| 354 | cacheData.runrecs[file_name] = {} | 358 | cacheData.runrecs[file_name] = {} | 
| 355 | 359 | ||
| 356 | rdepends = bb.utils.explode_deps(self.getVar('RDEPENDS', file_name, True) or "") | 360 | rdepends = self.getVar('RDEPENDS', file_name, True) or "" | 
| 357 | rrecommends = bb.utils.explode_deps(self.getVar('RRECOMMENDS', file_name, True) or "") | 361 | rrecommends = self.getVar('RRECOMMENDS', file_name, True) or "" | 
| 358 | for package in packages + [pn]: | 362 | for package in packages + [pn]: | 
| 359 | if not package in cacheData.rundeps[file_name]: | 363 | if not package in cacheData.rundeps[file_name]: | 
| 360 | cacheData.rundeps[file_name][package] = {} | 364 | cacheData.rundeps[file_name][package] = [] | 
| 361 | if not package in cacheData.runrecs[file_name]: | 365 | if not package in cacheData.runrecs[file_name]: | 
| 362 | cacheData.runrecs[file_name][package] = {} | 366 | cacheData.runrecs[file_name][package] = [] | 
| 363 | 367 | ||
| 364 | add_dep(cacheData.rundeps[file_name][package], rdepends) | 368 | cacheData.rundeps[file_name][package] = rdepends + " " + (self.getVar("RDEPENDS_%s" % package, file_name, True) or "") | 
| 365 | add_dep(cacheData.runrecs[file_name][package], rrecommends) | 369 | cacheData.runrecs[file_name][package] = rrecommends + " " + (self.getVar("RRECOMMENDS_%s" % package, file_name, True) or "") | 
| 366 | add_dep(cacheData.rundeps[file_name][package], bb.utils.explode_deps(self.getVar("RDEPENDS_%s" % package, file_name, True) or "")) | ||
| 367 | add_dep(cacheData.runrecs[file_name][package], bb.utils.explode_deps(self.getVar("RRECOMMENDS_%s" % package, file_name, True) or "")) | ||
| 368 | 370 | ||
| 369 | # Collect files we may need for possible world-dep | 371 | # Collect files we may need for possible world-dep | 
| 370 | # calculations | 372 | # calculations | 
| @@ -385,7 +387,7 @@ class Cache: | |||
| 385 | data.setVar('TMPDIR', data.getVar('TMPDIR', config, 1) or "", config) | 387 | data.setVar('TMPDIR', data.getVar('TMPDIR', config, 1) or "", config) | 
| 386 | bbfile_loc = os.path.abspath(os.path.dirname(bbfile)) | 388 | bbfile_loc = os.path.abspath(os.path.dirname(bbfile)) | 
| 387 | oldpath = os.path.abspath(os.getcwd()) | 389 | oldpath = os.path.abspath(os.getcwd()) | 
| 388 | if self.mtime(bbfile_loc): | 390 | if bb.parse.cached_mtime_noerror(bbfile_loc): | 
| 389 | os.chdir(bbfile_loc) | 391 | os.chdir(bbfile_loc) | 
| 390 | bb_data = data.init_db(config) | 392 | bb_data = data.init_db(config) | 
| 391 | try: | 393 | try: | 
| @@ -444,7 +446,7 @@ class CacheData: | |||
| 444 | self.pkg_dp = {} | 446 | self.pkg_dp = {} | 
| 445 | self.pn_provides = {} | 447 | self.pn_provides = {} | 
| 446 | self.fn_provides = {} | 448 | self.fn_provides = {} | 
| 447 | self.all_depends = Set() | 449 | self.all_depends = [] | 
| 448 | self.deps = {} | 450 | self.deps = {} | 
| 449 | self.rundeps = {} | 451 | self.rundeps = {} | 
| 450 | self.runrecs = {} | 452 | self.runrecs = {} | 
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 38a8209760..619791f174 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py  | |||
| @@ -473,11 +473,11 @@ class BBCooker: | |||
| 473 | 473 | ||
| 474 | # Load data into the cache for fn | 474 | # Load data into the cache for fn | 
| 475 | self.bb_cache = bb.cache.init(self) | 475 | self.bb_cache = bb.cache.init(self) | 
| 476 | self.bb_cache.loadData(fn, self.configuration.data) | 476 | self.bb_cache.loadData(fn, self.configuration.data) | 
| 477 | 477 | ||
| 478 | # Parse the loaded cache data | 478 | # Parse the loaded cache data | 
| 479 | self.status = bb.cache.CacheData() | 479 | self.status = bb.cache.CacheData() | 
| 480 | self.bb_cache.handle_data(fn, self.status) | 480 | self.bb_cache.handle_data(fn, self.status) | 
| 481 | 481 | ||
| 482 | # Tweak some variables | 482 | # Tweak some variables | 
| 483 | item = self.bb_cache.getVar('PN', fn, True) | 483 | item = self.bb_cache.getVar('PN', fn, True) | 
| @@ -493,7 +493,7 @@ class BBCooker: | |||
| 493 | # Remove stamp for target if force mode active | 493 | # Remove stamp for target if force mode active | 
| 494 | if self.configuration.force: | 494 | if self.configuration.force: | 
| 495 | bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (self.configuration.cmd, fn)) | 495 | bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (self.configuration.cmd, fn)) | 
| 496 | bb.build.del_stamp('do_%s' % self.configuration.cmd, bbfile_data) | 496 | bb.build.del_stamp('do_%s' % self.configuration.cmd, self.configuration.data) | 
| 497 | 497 | ||
| 498 | # Setup taskdata structure | 498 | # Setup taskdata structure | 
| 499 | taskdata = bb.taskdata.TaskData(self.configuration.abort) | 499 | taskdata = bb.taskdata.TaskData(self.configuration.abort) | 
| @@ -573,6 +573,7 @@ class BBCooker: | |||
| 573 | 573 | ||
| 574 | bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") | 574 | bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") | 
| 575 | (filelist, masked) = self.collect_bbfiles() | 575 | (filelist, masked) = self.collect_bbfiles() | 
| 576 | bb.data.renameVar("__depends", "__base_depends", self.configuration.data) | ||
| 576 | self.parse_bbfiles(filelist, masked, self.myProgressCallback) | 577 | self.parse_bbfiles(filelist, masked, self.myProgressCallback) | 
| 577 | bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") | 578 | bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") | 
| 578 | 579 | ||
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 2765343a3e..7b3defd343 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py  | |||
| @@ -317,6 +317,7 @@ class RunQueue: | |||
| 317 | 317 | ||
| 318 | depends = [] | 318 | depends = [] | 
| 319 | runq_build = [] | 319 | runq_build = [] | 
| 320 | recursive_tdepends = {} | ||
| 320 | 321 | ||
| 321 | taskData = self.taskData | 322 | taskData = self.taskData | 
| 322 | 323 | ||
| @@ -382,14 +383,45 @@ class RunQueue: | |||
| 382 | # e.g. do_sometask[depends] = "targetname:do_someothertask" | 383 | # e.g. do_sometask[depends] = "targetname:do_someothertask" | 
| 383 | # (makes sure sometask runs after targetname's someothertask) | 384 | # (makes sure sometask runs after targetname's someothertask) | 
| 384 | idepends = taskData.tasks_idepends[task] | 385 | idepends = taskData.tasks_idepends[task] | 
| 385 | for idepend in idepends: | 386 | for (depid, idependtask) in idepends: | 
| 386 | depid = int(idepend.split(":")[0]) | ||
| 387 | if depid in taskData.build_targets: | 387 | if depid in taskData.build_targets: | 
| 388 | # Won't be in build_targets if ASSUME_PROVIDED | 388 | # Won't be in build_targets if ASSUME_PROVIDED | 
| 389 | depdata = taskData.build_targets[depid][0] | 389 | depdata = taskData.build_targets[depid][0] | 
| 390 | if depdata is not None: | 390 | if depdata is not None: | 
| 391 | dep = taskData.fn_index[depdata] | 391 | dep = taskData.fn_index[depdata] | 
| 392 | depends.append(taskData.gettask_id(dep, idepend.split(":")[1])) | 392 | depends.append(taskData.gettask_id(dep, idependtask)) | 
| 393 | |||
| 394 | # Create a list of recursive dependent tasks (from tdepends) and cache | ||
| 395 | def get_recursive_tdepends(task): | ||
| 396 | if not task: | ||
| 397 | return [] | ||
| 398 | if task in recursive_tdepends: | ||
| 399 | return recursive_tdepends[task] | ||
| 400 | rectdepends = [task] | ||
| 401 | nextdeps = [task] | ||
| 402 | while len(nextdeps) != 0: | ||
| 403 | newdeps = [] | ||
| 404 | for nextdep in nextdeps: | ||
| 405 | for tdepend in taskData.tasks_tdepends[nextdep]: | ||
| 406 | if tdepend not in rectdepends: | ||
| 407 | rectdepends.append(tdepend) | ||
| 408 | newdeps.append(tdepend) | ||
| 409 | nextdeps = newdeps | ||
| 410 | recursive_tdepends[task] = rectdepends | ||
| 411 | return rectdepends | ||
| 412 | |||
| 413 | # Using the list of tdepends for this task create a list of | ||
| 414 | # the recursive idepends we have | ||
| 415 | def get_recursive_idepends(task): | ||
| 416 | if not task: | ||
| 417 | return [] | ||
| 418 | rectdepends = get_recursive_tdepends(task) | ||
| 419 | |||
| 420 | recidepends = [] | ||
| 421 | for tdepend in rectdepends: | ||
| 422 | for idepend in taskData.tasks_idepends[tdepend]: | ||
| 423 | recidepends.append(idepend) | ||
| 424 | return recidepends | ||
| 393 | 425 | ||
| 394 | def add_recursive_build(depid, depfnid): | 426 | def add_recursive_build(depid, depfnid): | 
| 395 | """ | 427 | """ | 
| @@ -404,13 +436,11 @@ class RunQueue: | |||
| 404 | depdata = taskData.build_targets[depid][0] | 436 | depdata = taskData.build_targets[depid][0] | 
| 405 | if depdata is not None: | 437 | if depdata is not None: | 
| 406 | dep = taskData.fn_index[depdata] | 438 | dep = taskData.fn_index[depdata] | 
| 407 | idepends = [] | ||
| 408 | # Need to avoid creating new tasks here | 439 | # Need to avoid creating new tasks here | 
| 409 | taskid = taskData.gettask_id(dep, taskname, False) | 440 | taskid = taskData.gettask_id(dep, taskname, False) | 
| 410 | if taskid is not None: | 441 | if taskid is not None: | 
| 411 | depends.append(taskid) | 442 | depends.append(taskid) | 
| 412 | fnid = taskData.tasks_fnid[taskid] | 443 | fnid = taskData.tasks_fnid[taskid] | 
| 413 | idepends = taskData.tasks_idepends[taskid] | ||
| 414 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | 444 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | 
| 415 | else: | 445 | else: | 
| 416 | fnid = taskData.getfn_id(dep) | 446 | fnid = taskData.getfn_id(dep) | 
| @@ -420,10 +450,9 @@ class RunQueue: | |||
| 420 | for nextdepid in taskData.rdepids[fnid]: | 450 | for nextdepid in taskData.rdepids[fnid]: | 
| 421 | if nextdepid not in rdep_seen: | 451 | if nextdepid not in rdep_seen: | 
| 422 | add_recursive_run(nextdepid, fnid) | 452 | add_recursive_run(nextdepid, fnid) | 
| 423 | for idepend in idepends: | 453 | for (idependid, idependtask) in get_recursive_idepends(taskid): | 
| 424 | nextdepid = int(idepend.split(":")[0]) | 454 | if idependid not in dep_seen: | 
| 425 | if nextdepid not in dep_seen: | 455 | add_recursive_build(idependid, fnid) | 
| 426 | add_recursive_build(nextdepid, fnid) | ||
| 427 | 456 | ||
| 428 | def add_recursive_run(rdepid, depfnid): | 457 | def add_recursive_run(rdepid, depfnid): | 
| 429 | """ | 458 | """ | 
| @@ -438,13 +467,11 @@ class RunQueue: | |||
| 438 | depdata = taskData.run_targets[rdepid][0] | 467 | depdata = taskData.run_targets[rdepid][0] | 
| 439 | if depdata is not None: | 468 | if depdata is not None: | 
| 440 | dep = taskData.fn_index[depdata] | 469 | dep = taskData.fn_index[depdata] | 
| 441 | idepends = [] | ||
| 442 | # Need to avoid creating new tasks here | 470 | # Need to avoid creating new tasks here | 
| 443 | taskid = taskData.gettask_id(dep, taskname, False) | 471 | taskid = taskData.gettask_id(dep, taskname, False) | 
| 444 | if taskid is not None: | 472 | if taskid is not None: | 
| 445 | depends.append(taskid) | 473 | depends.append(taskid) | 
| 446 | fnid = taskData.tasks_fnid[taskid] | 474 | fnid = taskData.tasks_fnid[taskid] | 
| 447 | idepends = taskData.tasks_idepends[taskid] | ||
| 448 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | 475 | #print "Added %s (%s) due to %s" % (taskid, taskData.fn_index[fnid], taskData.fn_index[depfnid]) | 
| 449 | else: | 476 | else: | 
| 450 | fnid = taskData.getfn_id(dep) | 477 | fnid = taskData.getfn_id(dep) | 
| @@ -454,10 +481,9 @@ class RunQueue: | |||
| 454 | for nextdepid in taskData.rdepids[fnid]: | 481 | for nextdepid in taskData.rdepids[fnid]: | 
| 455 | if nextdepid not in rdep_seen: | 482 | if nextdepid not in rdep_seen: | 
| 456 | add_recursive_run(nextdepid, fnid) | 483 | add_recursive_run(nextdepid, fnid) | 
| 457 | for idepend in idepends: | 484 | for (idependid, idependtask) in get_recursive_idepends(taskid): | 
| 458 | nextdepid = int(idepend.split(":")[0]) | 485 | if idependid not in dep_seen: | 
| 459 | if nextdepid not in dep_seen: | 486 | add_recursive_build(idependid, fnid) | 
| 460 | add_recursive_build(nextdepid, fnid) | ||
| 461 | 487 | ||
| 462 | # Resolve recursive 'recrdeptask' dependencies | 488 | # Resolve recursive 'recrdeptask' dependencies | 
| 463 | # | 489 | # | 
| @@ -472,9 +498,9 @@ class RunQueue: | |||
| 472 | add_recursive_build(depid, fnid) | 498 | add_recursive_build(depid, fnid) | 
| 473 | for rdepid in taskData.rdepids[fnid]: | 499 | for rdepid in taskData.rdepids[fnid]: | 
| 474 | add_recursive_run(rdepid, fnid) | 500 | add_recursive_run(rdepid, fnid) | 
| 475 | for idepend in idepends: | 501 | deptaskid = taskData.gettask_id(fn, taskname, False) | 
| 476 | depid = int(idepend.split(":")[0]) | 502 | for (idependid, idependtask) in get_recursive_idepends(deptaskid): | 
| 477 | add_recursive_build(depid, fnid) | 503 | add_recursive_build(idependid, fnid) | 
| 478 | 504 | ||
| 479 | # Rmove all self references | 505 | # Rmove all self references | 
| 480 | if task in depends: | 506 | if task in depends: | 
| @@ -659,6 +685,16 @@ class RunQueue: | |||
| 659 | if len(self.runq_depends[task]) == 0: | 685 | if len(self.runq_depends[task]) == 0: | 
| 660 | buildable.append(task) | 686 | buildable.append(task) | 
| 661 | 687 | ||
| 688 | def check_buildable(self, task, buildable): | ||
| 689 | for revdep in self.runq_revdeps[task]: | ||
| 690 | alldeps = 1 | ||
| 691 | for dep in self.runq_depends[revdep]: | ||
| 692 | if dep in unchecked: | ||
| 693 | alldeps = 0 | ||
| 694 | if alldeps == 1: | ||
| 695 | if revdep in unchecked: | ||
| 696 | buildable.append(revdep) | ||
| 697 | |||
| 662 | for task in range(len(self.runq_fnid)): | 698 | for task in range(len(self.runq_fnid)): | 
| 663 | if task not in unchecked: | 699 | if task not in unchecked: | 
| 664 | continue | 700 | continue | 
| @@ -669,12 +705,14 @@ class RunQueue: | |||
| 669 | if not os.access(stampfile, os.F_OK): | 705 | if not os.access(stampfile, os.F_OK): | 
| 670 | del unchecked[task] | 706 | del unchecked[task] | 
| 671 | notcurrent.append(task) | 707 | notcurrent.append(task) | 
| 708 | check_buildable(self, task, buildable) | ||
| 672 | continue | 709 | continue | 
| 673 | # If its a 'nostamp' task, it's not current | 710 | # If its a 'nostamp' task, it's not current | 
| 674 | taskdep = self.dataCache.task_deps[fn] | 711 | taskdep = self.dataCache.task_deps[fn] | 
| 675 | if 'nostamp' in taskdep and task in taskdep['nostamp']: | 712 | if 'nostamp' in taskdep and task in taskdep['nostamp']: | 
| 676 | del unchecked[task] | 713 | del unchecked[task] | 
| 677 | notcurrent.append(task) | 714 | notcurrent.append(task) | 
| 715 | check_buildable(self, task, buildable) | ||
| 678 | continue | 716 | continue | 
| 679 | 717 | ||
| 680 | while (len(buildable) > 0): | 718 | while (len(buildable) > 0): | 
| @@ -705,14 +743,7 @@ class RunQueue: | |||
| 705 | else: | 743 | else: | 
| 706 | notcurrent.append(task) | 744 | notcurrent.append(task) | 
| 707 | 745 | ||
| 708 | for revdep in self.runq_revdeps[task]: | 746 | check_buildable(self, task, nextbuildable) | 
| 709 | alldeps = 1 | ||
| 710 | for dep in self.runq_depends[revdep]: | ||
| 711 | if dep in unchecked: | ||
| 712 | alldeps = 0 | ||
| 713 | if alldeps == 1: | ||
| 714 | if revdep in unchecked: | ||
| 715 | nextbuildable.append(revdep) | ||
| 716 | 747 | ||
| 717 | buildable = nextbuildable | 748 | buildable = nextbuildable | 
| 718 | 749 | ||
| @@ -729,6 +760,40 @@ class RunQueue: | |||
| 729 | bb.fatal("check_stamps fatal internal error") | 760 | bb.fatal("check_stamps fatal internal error") | 
| 730 | return current | 761 | return current | 
| 731 | 762 | ||
| 763 | def check_stamp(self, task): | ||
| 764 | |||
| 765 | if self.stamppolicy == "perfile": | ||
| 766 | fulldeptree = False | ||
| 767 | else: | ||
| 768 | fulldeptree = True | ||
| 769 | |||
| 770 | fn = self.taskData.fn_index[self.runq_fnid[task]] | ||
| 771 | taskname = self.runq_task[task] | ||
| 772 | stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname) | ||
| 773 | # If the stamp is missing its not current | ||
| 774 | if not os.access(stampfile, os.F_OK): | ||
| 775 | return False | ||
| 776 | # If its a 'nostamp' task, it's not current | ||
| 777 | taskdep = self.dataCache.task_deps[fn] | ||
| 778 | if 'nostamp' in taskdep and task in taskdep['nostamp']: | ||
| 779 | return False | ||
| 780 | |||
| 781 | iscurrent = True | ||
| 782 | t1 = os.stat(stampfile)[stat.ST_MTIME] | ||
| 783 | for dep in self.runq_depends[task]: | ||
| 784 | if iscurrent: | ||
| 785 | fn2 = self.taskData.fn_index[self.runq_fnid[dep]] | ||
| 786 | taskname2 = self.runq_task[dep] | ||
| 787 | stampfile2 = "%s.%s" % (self.dataCache.stamp[fn2], taskname2) | ||
| 788 | if fulldeptree or fn == fn2: | ||
| 789 | try: | ||
| 790 | t2 = os.stat(stampfile2)[stat.ST_MTIME] | ||
| 791 | if t1 < t2: | ||
| 792 | iscurrent = False | ||
| 793 | except: | ||
| 794 | iscurrent = False | ||
| 795 | |||
| 796 | return iscurrent | ||
| 732 | 797 | ||
| 733 | def execute_runqueue(self): | 798 | def execute_runqueue(self): | 
| 734 | """ | 799 | """ | 
| @@ -817,25 +882,18 @@ class RunQueue: | |||
| 817 | 882 | ||
| 818 | event.fire(bb.event.StampUpdate(self.target_pairs, self.dataCache.stamp, self.cfgdata)) | 883 | event.fire(bb.event.StampUpdate(self.target_pairs, self.dataCache.stamp, self.cfgdata)) | 
| 819 | 884 | ||
| 820 | # Find out which tasks have current stamps which we can skip when the | ||
| 821 | # time comes | ||
| 822 | currentstamps = self.check_stamps() | ||
| 823 | self.stats.taskSkipped(len(currentstamps)) | ||
| 824 | self.stats.taskCompleted(len(currentstamps)) | ||
| 825 | |||
| 826 | while True: | 885 | while True: | 
| 827 | task = self.sched.next() | 886 | task = self.sched.next() | 
| 828 | if task is not None: | 887 | if task is not None: | 
| 829 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 888 | fn = self.taskData.fn_index[self.runq_fnid[task]] | 
| 830 | 889 | ||
| 831 | taskname = self.runq_task[task] | 890 | taskname = self.runq_task[task] | 
| 832 | if task in currentstamps: | 891 | if self.check_stamp(task): | 
| 833 | #if bb.build.stamp_is_current(taskname, self.dataCache, fn): | ||
| 834 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task))) | 892 | bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task))) | 
| 835 | self.runq_running[task] = 1 | 893 | self.runq_running[task] = 1 | 
| 836 | self.task_complete(task) | 894 | self.task_complete(task) | 
| 837 | #self.stats.taskCompleted() | 895 | self.stats.taskCompleted() | 
| 838 | #self.stats.taskSkipped() | 896 | self.stats.taskSkipped() | 
| 839 | continue | 897 | continue | 
| 840 | 898 | ||
| 841 | bb.msg.note(1, bb.msg.domain.RunQueue, "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.active_builds + 1, len(self.runq_fnid), task, self.get_user_idstring(task))) | 899 | bb.msg.note(1, bb.msg.domain.RunQueue, "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.active_builds + 1, len(self.runq_fnid), task, self.get_user_idstring(task))) | 
diff --git a/bitbake/lib/bb/taskdata.py b/bitbake/lib/bb/taskdata.py index 4a79e7a56d..0fb34ad748 100644 --- a/bitbake/lib/bb/taskdata.py +++ b/bitbake/lib/bb/taskdata.py  | |||
| @@ -150,7 +150,7 @@ class TaskData: | |||
| 150 | ids = [] | 150 | ids = [] | 
| 151 | for dep in task_deps['depends'][task].split(): | 151 | for dep in task_deps['depends'][task].split(): | 
| 152 | if dep: | 152 | if dep: | 
| 153 | ids.append(str(self.getbuild_id(dep.split(":")[0])) + ":" + dep.split(":")[1]) | 153 | ids.append(((self.getbuild_id(dep.split(":")[0])), dep.split(":")[1])) | 
| 154 | self.tasks_idepends[taskid].extend(ids) | 154 | self.tasks_idepends[taskid].extend(ids) | 
| 155 | 155 | ||
| 156 | # Work out build dependencies | 156 | # Work out build dependencies | 
| @@ -167,11 +167,11 @@ class TaskData: | |||
| 167 | rdepends = dataCache.rundeps[fn] | 167 | rdepends = dataCache.rundeps[fn] | 
| 168 | rrecs = dataCache.runrecs[fn] | 168 | rrecs = dataCache.runrecs[fn] | 
| 169 | for package in rdepends: | 169 | for package in rdepends: | 
| 170 | for rdepend in rdepends[package]: | 170 | for rdepend in bb.utils.explode_deps(rdepends[package]): | 
| 171 | bb.msg.debug(2, bb.msg.domain.TaskData, "Added runtime dependency %s for %s" % (rdepend, fn)) | 171 | bb.msg.debug(2, bb.msg.domain.TaskData, "Added runtime dependency %s for %s" % (rdepend, fn)) | 
| 172 | rdependids[self.getrun_id(rdepend)] = None | 172 | rdependids[self.getrun_id(rdepend)] = None | 
| 173 | for package in rrecs: | 173 | for package in rrecs: | 
| 174 | for rdepend in rrecs[package]: | 174 | for rdepend in bb.utils.explode_deps(rrecs[package]): | 
| 175 | bb.msg.debug(2, bb.msg.domain.TaskData, "Added runtime recommendation %s for %s" % (rdepend, fn)) | 175 | bb.msg.debug(2, bb.msg.domain.TaskData, "Added runtime recommendation %s for %s" % (rdepend, fn)) | 
| 176 | rdependids[self.getrun_id(rdepend)] = None | 176 | rdependids[self.getrun_id(rdepend)] = None | 
| 177 | self.rdepids[fnid] = rdependids.keys() | 177 | self.rdepids[fnid] = rdependids.keys() | 
| @@ -458,8 +458,6 @@ class TaskData: | |||
| 458 | """ | 458 | """ | 
| 459 | if fnid in self.failed_fnids: | 459 | if fnid in self.failed_fnids: | 
| 460 | return | 460 | return | 
| 461 | if not missing_list: | ||
| 462 | missing_list = [fnid] | ||
| 463 | bb.msg.debug(1, bb.msg.domain.Provider, "File '%s' is unbuildable, removing..." % self.fn_index[fnid]) | 461 | bb.msg.debug(1, bb.msg.domain.Provider, "File '%s' is unbuildable, removing..." % self.fn_index[fnid]) | 
| 464 | self.failed_fnids.append(fnid) | 462 | self.failed_fnids.append(fnid) | 
| 465 | for target in self.build_targets: | 463 | for target in self.build_targets: | 
| @@ -487,6 +485,12 @@ class TaskData: | |||
| 487 | dependees = self.get_dependees(targetid) | 485 | dependees = self.get_dependees(targetid) | 
| 488 | for fnid in dependees: | 486 | for fnid in dependees: | 
| 489 | self.fail_fnid(fnid, missing_list) | 487 | self.fail_fnid(fnid, missing_list) | 
| 488 | for taskid in range(len(self.tasks_idepends)): | ||
| 489 | idepends = self.tasks_idepends[taskid] | ||
| 490 | for (idependid, idependtask) in idepends: | ||
| 491 | if idependid == targetid: | ||
| 492 | self.fail_fnid(self.tasks_fnid[taskid], missing_list) | ||
| 493 | |||
| 490 | if self.abort and targetid in self.external_targets: | 494 | if self.abort and targetid in self.external_targets: | 
| 491 | bb.msg.error(bb.msg.domain.Provider, "Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s" % (self.build_names_index[targetid], missing_list)) | 495 | bb.msg.error(bb.msg.domain.Provider, "Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s" % (self.build_names_index[targetid], missing_list)) | 
| 492 | raise bb.providers.NoProvider | 496 | raise bb.providers.NoProvider | 
