[OE-core] [PATCH 1/4] insane.bbclass: add QA check: package-missing
Hongxu Jia
hongxu.jia at windriver.com
Thu Dec 11 10:27:22 UTC 2014
During packaging, check if there are any dependencies (RDEPENDS)
on packages that have ended up empty and not produced; and if so
produce an warn/error as soon as possible, instead of allowing
the build to proceed up to do_rootfs and then the package manager
reporting the package as missing.
At the moment, we use bb.persist_data as a global database to
collect all available packages rdepends and rprovides. So in the
do_package_qa task, while package not produced, we could compute
rdepends chain, and report warn/error immediately.
[YOCTO #5531]
[YOCTO #6420]
Signed-off-by: Hongxu Jia <hongxu.jia at windriver.com>
---
meta/classes/insane.bbclass | 93 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 1 deletion(-)
diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
index 0b45374..a0eff37 100644
--- a/meta/classes/insane.bbclass
+++ b/meta/classes/insane.bbclass
@@ -29,7 +29,7 @@ QA_SANE = "True"
WARN_QA ?= "ldflags useless-rpaths rpaths staticdev libdir xorg-driver-abi \
textrel already-stripped incompatible-license files-invalid \
installed-vs-shipped compile-host-path install-host-path \
- pn-overrides infodir build-deps file-rdeps \
+ pn-overrides infodir build-deps file-rdeps package-missing \
"
ERROR_QA ?= "dev-so debug-deps dev-deps debug-files arch pkgconfig la \
perms dep-cmp pkgvarcheck perm-config perm-line perm-link \
@@ -868,6 +868,15 @@ def package_qa_check_rdepends(pkg, pkgdest, skip, taskdeps, packages, d):
(pkg, ', '.join(str(e) for e in filerdepends))
sane = package_qa_handle_error("file-rdeps", error_msg, d)
+ if "package-missing" not in skip and \
+ not pkg.endswith("-dev") and not pkg.endswith("-staticdev") and \
+ not pkg.endswith("-locale") and not pkg.endswith("-dbg") and \
+ not pkg.endswith("-doc"):
+ if not oe.packagedata.packaged(pkg, d):
+ error_msg = "package %s not generated, but listed in PACKAGES\n" % pkg
+ error_msg += compute_rdepends_chain(pkg, d)
+ sane = package_qa_handle_error("package-missing", error_msg, d)
+
return sane
def package_qa_check_deps(pkg, pkgdest, skip, d):
@@ -1152,3 +1161,85 @@ python () {
for i in issues:
package_qa_handle_error("pkgvarcheck", "%s: Variable %s is set as not being package specific, please fix this." % (d.getVar("FILE", True), i), d)
}
+
+# Add a handler to collect all available packages rdepends and rprovides
+# to a global database (bb.persist_data). So the recipe could find out
+# which others rdepends on it. We filter out "-dev, -staticdev, -locale,
+# -dbg, -doc" packages.
+# Such as:
+# RDEPENDS_pkg1 = "pkg2 pkg3"
+# RDEPENDS_pkg4 = "pkg3 pkg5"
+# equals:
+# rdeps_dict = {'pkg2': 'pkg1', 'pkg3': 'pkg1 pkg4', 'pkg5':'pkg4'}
+#
+# RPROVIDES_pkg6 = "pkg2 pkg7"
+# RPROVIDES_pkg7 = "pkg5"
+# equals:
+# rprovides_dict = {'pkg6': 'pkg2 pkg7', 'pkg7': 'pkg5'}
+python collect_package_rdepends_handler () {
+ d = e.data
+ pkgs = []
+ for pkg in (d.getVar('PACKAGES', True) or '').split():
+ if pkg.endswith("-dev") or pkg.endswith("-staticdev") or \
+ pkg.endswith("-locale") or pkg.endswith("-dbg") or \
+ pkg.endswith("-doc"):
+ continue
+ pkgs.append(pkg)
+
+ if not pkgs:
+ return
+
+ rdeps_dict = bb.persist_data.persist('BB_RDEPENDED_CHAIN', d)
+ for pkg in pkgs:
+ rdeps = (d.getVar('RDEPENDS_%s' % pkg, True) or "").split()
+ for rdep in rdeps:
+ # Filter out pkg which rdepends itself
+ if pkg == rdep:
+ continue
+
+ if rdep in rdeps_dict and pkg not in rdeps_dict[rdep].split():
+ rdeps_dict[rdep] += ' %s' % pkg
+ elif rdep not in rdeps_dict:
+ rdeps_dict[rdep] = '%s' % pkg
+
+ rprovides_dict = bb.persist_data.persist('BB_RPROVIDES_CHAIN', d)
+ for pkg in pkgs:
+ rprovides = (d.getVar('RPROVIDES_%s' % pkg, True) or "").split()
+ if rprovides:
+ rprovides_dict[pkg] = ' '.join(set(rprovides))
+}
+addhandler collect_package_rdepends_handler
+collect_package_rdepends_handler[eventmask] = "bb.event.RecipeParsed"
+
+def compute_rdepends_chain(pkg, d):
+ rdeps_dict = bb.persist_data.persist('BB_RDEPENDED_CHAIN', d)
+ rprovides_dict = bb.persist_data.persist('BB_RPROVIDES_CHAIN', d)
+
+ def get_parents(pkg):
+ parents = []
+ message = ""
+
+ if pkg not in rdeps_dict and pkg in rprovides_dict:
+ for rprovide in rprovides_dict[pkg].split():
+ # Use rprovide to instead of pkg
+ if rprovide in rdeps_dict:
+ message = '("%s" rprovides "%s")\n' % (pkg, rprovide)
+ pkg = rprovide
+ break
+
+ if pkg in rdeps_dict:
+ parents = rdeps_dict[pkg].split()
+ for parent in parents:
+ message += '"%s" -> "%s"\n' % (parent, pkg)
+
+ for parent in parents:
+ message += get_parents(parent)
+
+ return message
+
+ message = get_parents(pkg)
+ if message:
+ message = "Compute rdepends chains, '-->' means 'runtime depends'\n" \
+ + message
+ return message
+
--
1.9.1
More information about the Openembedded-core
mailing list