diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2011-07-25 14:54:41 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-07-27 16:54:04 +0100 |
commit | daed107ce188c6ae53a3d612de58885f23b7257e (patch) | |
tree | 5ae56653c3b71b6c23d3aba01c4b6abafd27b16f /bitbake | |
parent | 60218d19f7c3651908e352e5e001257fd34d138b (diff) | |
download | poky-daed107ce188c6ae53a3d612de58885f23b7257e.tar.gz |
bitbake: show more information for NoProvider errors
"Nothing PROVIDES" errors often come up when a recipe has been skipped
for some reason, and therefore it is useful to print out that reason
information when showing the error so that the user understands why the
error has occurred.
Given that we already feed the reason information into the skiplist for
various situations (COMMERCIAL_LICENSE, COMPATIBLE_MACHINE etc.) this
should now output a useful error message for skipped recipes.
Fixes [YOCTO #846], [YOCTO #1127]
(Bitbake rev: 6765218430e31c165888f26fbc75023c89a6eab2)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/cache.py | 3 | ||||
-rw-r--r-- | bitbake/lib/bb/cooker.py | 6 | ||||
-rw-r--r-- | bitbake/lib/bb/event.py | 3 | ||||
-rw-r--r-- | bitbake/lib/bb/taskdata.py | 28 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/knotty.py | 3 |
5 files changed, 34 insertions, 9 deletions
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py index 58d5847f15..d805d46d07 100644 --- a/bitbake/lib/bb/cache.py +++ b/bitbake/lib/bb/cache.py | |||
@@ -43,7 +43,7 @@ except ImportError: | |||
43 | logger.info("Importing cPickle failed. " | 43 | logger.info("Importing cPickle failed. " |
44 | "Falling back to a very slow implementation.") | 44 | "Falling back to a very slow implementation.") |
45 | 45 | ||
46 | __cache_version__ = "141" | 46 | __cache_version__ = "142" |
47 | 47 | ||
48 | def getCacheFile(path, filename): | 48 | def getCacheFile(path, filename): |
49 | return os.path.join(path, filename) | 49 | return os.path.join(path, filename) |
@@ -99,6 +99,7 @@ class CoreRecipeInfo(RecipeInfoCommon): | |||
99 | 99 | ||
100 | self.skipreason = self.getvar('__SKIPPED', metadata) | 100 | self.skipreason = self.getvar('__SKIPPED', metadata) |
101 | if self.skipreason: | 101 | if self.skipreason: |
102 | self.pn = self.getvar('PN', metadata) or bb.parse.BBHandler.vars_from_file(filename,metadata)[0] | ||
102 | self.skipped = True | 103 | self.skipped = True |
103 | self.provides = self.depvar('PROVIDES', metadata) | 104 | self.provides = self.depvar('PROVIDES', metadata) |
104 | self.rprovides = self.depvar('RPROVIDES', metadata) | 105 | self.rprovides = self.depvar('RPROVIDES', metadata) |
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 9d0a6d49b5..33b684fbd8 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -59,11 +59,13 @@ class state: | |||
59 | 59 | ||
60 | class SkippedPackage: | 60 | class SkippedPackage: |
61 | def __init__(self, info = None, reason = None): | 61 | def __init__(self, info = None, reason = None): |
62 | self.pn = None | ||
62 | self.skipreason = None | 63 | self.skipreason = None |
63 | self.provides = None | 64 | self.provides = None |
64 | self.rprovides = None | 65 | self.rprovides = None |
65 | 66 | ||
66 | if info: | 67 | if info: |
68 | self.pn = info.pn | ||
67 | self.skipreason = info.skipreason | 69 | self.skipreason = info.skipreason |
68 | self.provides = info.provides | 70 | self.provides = info.provides |
69 | self.rprovides = info.rprovides | 71 | self.rprovides = info.rprovides |
@@ -328,7 +330,7 @@ class BBCooker: | |||
328 | bb.data.expandKeys(localdata) | 330 | bb.data.expandKeys(localdata) |
329 | # We set abort to False here to prevent unbuildable targets raising | 331 | # We set abort to False here to prevent unbuildable targets raising |
330 | # an exception when we're just generating data | 332 | # an exception when we're just generating data |
331 | taskdata = bb.taskdata.TaskData(False) | 333 | taskdata = bb.taskdata.TaskData(False, skiplist=self.skiplist) |
332 | 334 | ||
333 | runlist = [] | 335 | runlist = [] |
334 | for k in pkgs_to_build: | 336 | for k in pkgs_to_build: |
@@ -1060,7 +1062,7 @@ class BBCooker: | |||
1060 | bb.data.update_data(localdata) | 1062 | bb.data.update_data(localdata) |
1061 | bb.data.expandKeys(localdata) | 1063 | bb.data.expandKeys(localdata) |
1062 | 1064 | ||
1063 | taskdata = bb.taskdata.TaskData(self.configuration.abort) | 1065 | taskdata = bb.taskdata.TaskData(self.configuration.abort, skiplist=self.skiplist) |
1064 | 1066 | ||
1065 | runlist = [] | 1067 | runlist = [] |
1066 | for k in targets: | 1068 | for k in targets: |
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 93c04ba21a..9dd7b663ee 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
@@ -287,11 +287,12 @@ class BuildCompleted(BuildBase): | |||
287 | class NoProvider(Event): | 287 | class NoProvider(Event): |
288 | """No Provider for an Event""" | 288 | """No Provider for an Event""" |
289 | 289 | ||
290 | def __init__(self, item, runtime=False, dependees=None): | 290 | def __init__(self, item, runtime=False, dependees=None, reasons=[]): |
291 | Event.__init__(self) | 291 | Event.__init__(self) |
292 | self._item = item | 292 | self._item = item |
293 | self._runtime = runtime | 293 | self._runtime = runtime |
294 | self._dependees = dependees | 294 | self._dependees = dependees |
295 | self._reasons = reasons | ||
295 | 296 | ||
296 | def getItem(self): | 297 | def getItem(self): |
297 | return self._item | 298 | return self._item |
diff --git a/bitbake/lib/bb/taskdata.py b/bitbake/lib/bb/taskdata.py index 81a42b7b53..e857f9afcb 100644 --- a/bitbake/lib/bb/taskdata.py +++ b/bitbake/lib/bb/taskdata.py | |||
@@ -41,7 +41,7 @@ class TaskData: | |||
41 | """ | 41 | """ |
42 | BitBake Task Data implementation | 42 | BitBake Task Data implementation |
43 | """ | 43 | """ |
44 | def __init__(self, abort = True, tryaltconfigs = False): | 44 | def __init__(self, abort = True, tryaltconfigs = False, skiplist = None): |
45 | self.build_names_index = [] | 45 | self.build_names_index = [] |
46 | self.run_names_index = [] | 46 | self.run_names_index = [] |
47 | self.fn_index = [] | 47 | self.fn_index = [] |
@@ -70,6 +70,8 @@ class TaskData: | |||
70 | self.abort = abort | 70 | self.abort = abort |
71 | self.tryaltconfigs = tryaltconfigs | 71 | self.tryaltconfigs = tryaltconfigs |
72 | 72 | ||
73 | self.skiplist = skiplist | ||
74 | |||
73 | def getbuild_id(self, name): | 75 | def getbuild_id(self, name): |
74 | """ | 76 | """ |
75 | Return an ID number for the build target name. | 77 | Return an ID number for the build target name. |
@@ -348,6 +350,22 @@ class TaskData: | |||
348 | dependees.append(self.fn_index[fnid]) | 350 | dependees.append(self.fn_index[fnid]) |
349 | return dependees | 351 | return dependees |
350 | 352 | ||
353 | def get_reasons(self, item, runtime=False): | ||
354 | """ | ||
355 | Get the reason(s) for an item not being provided, if any | ||
356 | """ | ||
357 | reasons = [] | ||
358 | if self.skiplist: | ||
359 | for fn in self.skiplist: | ||
360 | skipitem = self.skiplist[fn] | ||
361 | if skipitem.pn == item: | ||
362 | reasons.append("%s was skipped: %s" % (skipitem.pn, skipitem.skipreason)) | ||
363 | elif runtime and item in skipitem.rprovides: | ||
364 | reasons.append("%s RPROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason)) | ||
365 | elif not runtime and item in skipitem.provides: | ||
366 | reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason)) | ||
367 | return reasons | ||
368 | |||
351 | def add_provider(self, cfgData, dataCache, item): | 369 | def add_provider(self, cfgData, dataCache, item): |
352 | try: | 370 | try: |
353 | self.add_provider_internal(cfgData, dataCache, item) | 371 | self.add_provider_internal(cfgData, dataCache, item) |
@@ -369,7 +387,7 @@ class TaskData: | |||
369 | return | 387 | return |
370 | 388 | ||
371 | if not item in dataCache.providers: | 389 | if not item in dataCache.providers: |
372 | bb.event.fire(bb.event.NoProvider(item, dependees=self.get_rdependees_str(item)), cfgData) | 390 | bb.event.fire(bb.event.NoProvider(item, dependees=self.get_rdependees_str(item), reasons=self.get_reasons(item)), cfgData) |
373 | raise bb.providers.NoProvider(item) | 391 | raise bb.providers.NoProvider(item) |
374 | 392 | ||
375 | if self.have_build_target(item): | 393 | if self.have_build_target(item): |
@@ -381,7 +399,7 @@ class TaskData: | |||
381 | eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids] | 399 | eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids] |
382 | 400 | ||
383 | if not eligible: | 401 | if not eligible: |
384 | bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item)), cfgData) | 402 | bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item), reasons=["No eligible PROVIDERs exist for '%s'" % item]), cfgData) |
385 | raise bb.providers.NoProvider(item) | 403 | raise bb.providers.NoProvider(item) |
386 | 404 | ||
387 | if len(eligible) > 1 and foundUnique == False: | 405 | if len(eligible) > 1 and foundUnique == False: |
@@ -418,14 +436,14 @@ class TaskData: | |||
418 | all_p = bb.providers.getRuntimeProviders(dataCache, item) | 436 | all_p = bb.providers.getRuntimeProviders(dataCache, item) |
419 | 437 | ||
420 | if not all_p: | 438 | if not all_p: |
421 | bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item)), cfgData) | 439 | bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item), reasons=self.get_reasons(item, True)), cfgData) |
422 | raise bb.providers.NoRProvider(item) | 440 | raise bb.providers.NoRProvider(item) |
423 | 441 | ||
424 | eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache) | 442 | eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache) |
425 | eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids] | 443 | eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids] |
426 | 444 | ||
427 | if not eligible: | 445 | if not eligible: |
428 | bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item)), cfgData) | 446 | bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item), reasons=["No eligible RPROVIDERs exist for '%s'" % item]), cfgData) |
429 | raise bb.providers.NoRProvider(item) | 447 | raise bb.providers.NoRProvider(item) |
430 | 448 | ||
431 | if len(eligible) > 1 and numberPreferred == 0: | 449 | if len(eligible) > 1 and numberPreferred == 0: |
diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py index a4deb468bb..b7abdf8943 100644 --- a/bitbake/lib/bb/ui/knotty.py +++ b/bitbake/lib/bb/ui/knotty.py | |||
@@ -208,6 +208,9 @@ def main(server, eventHandler): | |||
208 | logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)", r, event._item, ", ".join(event._dependees), r) | 208 | logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)", r, event._item, ", ".join(event._dependees), r) |
209 | else: | 209 | else: |
210 | logger.error("Nothing %sPROVIDES '%s'", r, event._item) | 210 | logger.error("Nothing %sPROVIDES '%s'", r, event._item) |
211 | if event._reasons: | ||
212 | for reason in event._reasons: | ||
213 | logger.error("%s", reason) | ||
211 | continue | 214 | continue |
212 | 215 | ||
213 | if isinstance(event, bb.runqueue.runQueueTaskStarted): | 216 | if isinstance(event, bb.runqueue.runQueueTaskStarted): |