diff options
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 946aa980d3..e1b9b2e661 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -261,6 +261,13 @@ class RunQueueData: | |||
| 261 | taskname = self.runq_task[task] + task_name_suffix | 261 | taskname = self.runq_task[task] + task_name_suffix |
| 262 | return "%s, %s" % (fn, taskname) | 262 | return "%s, %s" % (fn, taskname) |
| 263 | 263 | ||
| 264 | def get_short_user_idstring(self, task, task_name_suffix = ""): | ||
| 265 | fn = self.taskData.fn_index[self.runq_fnid[task]] | ||
| 266 | pn = self.dataCache.pkg_fn[fn] | ||
| 267 | taskname = self.runq_task[task] + task_name_suffix | ||
| 268 | return "%s:%s" % (pn, taskname) | ||
| 269 | |||
| 270 | |||
| 264 | def get_task_id(self, fnid, taskname): | 271 | def get_task_id(self, fnid, taskname): |
| 265 | for listid in xrange(len(self.runq_fnid)): | 272 | for listid in xrange(len(self.runq_fnid)): |
| 266 | if self.runq_fnid[listid] == fnid and self.runq_task[listid] == taskname: | 273 | if self.runq_fnid[listid] == fnid and self.runq_task[listid] == taskname: |
| @@ -753,11 +760,72 @@ class RunQueueData: | |||
| 753 | seen_pn.append(pn) | 760 | seen_pn.append(pn) |
| 754 | else: | 761 | else: |
| 755 | bb.fatal("Multiple versions of %s are due to be built (%s). Only one version of a given PN should be built in any given build. You likely need to set PREFERRED_VERSION_%s to select the correct version or don't depend on multiple versions." % (pn, " ".join(prov_list[prov]), pn)) | 762 | bb.fatal("Multiple versions of %s are due to be built (%s). Only one version of a given PN should be built in any given build. You likely need to set PREFERRED_VERSION_%s to select the correct version or don't depend on multiple versions." % (pn, " ".join(prov_list[prov]), pn)) |
| 756 | msg = "Multiple .bb files are due to be built which each provide %s (%s)." % (prov, " ".join(prov_list[prov])) | 763 | msg = "Multiple .bb files are due to be built which each provide %s:\n %s" % (prov, "\n ".join(prov_list[prov])) |
| 764 | # | ||
| 765 | # Construct a list of things which uniquely depend on each provider | ||
| 766 | # since this may help the user figure out which dependency is triggering this warning | ||
| 767 | # | ||
| 768 | msg += "\nA list of tasks depending on these providers is shown and may help explain where the dependency comes from." | ||
| 769 | deplist = {} | ||
| 770 | commondeps = None | ||
| 771 | for provfn in prov_list[prov]: | ||
| 772 | deps = set() | ||
| 773 | for task, fnid in enumerate(self.runq_fnid): | ||
| 774 | fn = taskData.fn_index[fnid] | ||
| 775 | if fn != provfn: | ||
| 776 | continue | ||
| 777 | for dep in self.runq_revdeps[task]: | ||
| 778 | fn = taskData.fn_index[self.runq_fnid[dep]] | ||
| 779 | if fn == provfn: | ||
| 780 | continue | ||
| 781 | deps.add(self.get_short_user_idstring(dep)) | ||
| 782 | if not commondeps: | ||
| 783 | commondeps = set(deps) | ||
| 784 | else: | ||
| 785 | commondeps &= deps | ||
| 786 | deplist[provfn] = deps | ||
| 787 | for provfn in deplist: | ||
| 788 | msg += "\n%s has unique dependees:\n %s" % (provfn, "\n ".join(deplist[provfn] - commondeps)) | ||
| 789 | # | ||
| 790 | # Construct a list of provides and runtime providers for each recipe | ||
| 791 | # (rprovides has to cover RPROVIDES, PACKAGES, PACKAGES_DYNAMIC) | ||
| 792 | # | ||
| 793 | msg += "\nIt could be that one recipe provides something the other doesn't and should. The following provider and runtime provider differences may be helpful." | ||
| 794 | provide_results = {} | ||
| 795 | rprovide_results = {} | ||
| 796 | commonprovs = None | ||
| 797 | commonrprovs = None | ||
| 798 | for provfn in prov_list[prov]: | ||
| 799 | provides = set(self.dataCache.fn_provides[provfn]) | ||
| 800 | rprovides = set() | ||
| 801 | for rprovide in self.dataCache.rproviders: | ||
| 802 | if provfn in self.dataCache.rproviders[rprovide]: | ||
| 803 | rprovides.add(rprovide) | ||
| 804 | for package in self.dataCache.packages: | ||
| 805 | if provfn in self.dataCache.packages[package]: | ||
| 806 | rprovides.add(package) | ||
| 807 | for package in self.dataCache.packages_dynamic: | ||
| 808 | if provfn in self.dataCache.packages_dynamic[package]: | ||
| 809 | rprovides.add(package) | ||
| 810 | if not commonprovs: | ||
| 811 | commonprovs = set(provides) | ||
| 812 | else: | ||
| 813 | commonprovs &= provides | ||
| 814 | provide_results[provfn] = provides | ||
| 815 | if not commonrprovs: | ||
| 816 | commonrprovs = set(rprovides) | ||
| 817 | else: | ||
| 818 | commonrprovs &= rprovides | ||
| 819 | rprovide_results[provfn] = rprovides | ||
| 820 | #msg += "\nCommon provides:\n %s" % ("\n ".join(commonprovs)) | ||
| 821 | #msg += "\nCommon rprovides:\n %s" % ("\n ".join(commonrprovs)) | ||
| 822 | for provfn in prov_list[prov]: | ||
| 823 | msg += "\n%s has unique provides:\n %s" % (provfn, "\n ".join(provide_results[provfn] - commonprovs)) | ||
| 824 | msg += "\n%s has unique rprovides:\n %s" % (provfn, "\n ".join(rprovide_results[provfn] - commonrprovs)) | ||
| 825 | |||
| 757 | if self.warn_multi_bb: | 826 | if self.warn_multi_bb: |
| 758 | logger.warn(msg) | 827 | logger.warn(msg) |
| 759 | else: | 828 | else: |
| 760 | msg += "\n This usually means one provides something the other doesn't and should." | ||
| 761 | logger.error(msg) | 829 | logger.error(msg) |
| 762 | 830 | ||
| 763 | # Create a whitelist usable by the stamp checks | 831 | # Create a whitelist usable by the stamp checks |
