summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2011-07-25 14:54:41 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2011-07-27 16:54:04 +0100
commitdaed107ce188c6ae53a3d612de58885f23b7257e (patch)
tree5ae56653c3b71b6c23d3aba01c4b6abafd27b16f
parent60218d19f7c3651908e352e5e001257fd34d138b (diff)
downloadpoky-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>
-rw-r--r--bitbake/lib/bb/cache.py3
-rw-r--r--bitbake/lib/bb/cooker.py6
-rw-r--r--bitbake/lib/bb/event.py3
-rw-r--r--bitbake/lib/bb/taskdata.py28
-rw-r--r--bitbake/lib/bb/ui/knotty.py3
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
48def getCacheFile(path, filename): 48def 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
60class SkippedPackage: 60class 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):
287class NoProvider(Event): 287class 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):