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 |