aboutsummaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2013-01-25 16:35:10 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-01-31 14:00:03 +0000
commit8d80483e2f0f755a61087be1dffaf595fbc467fd (patch)
treebe7bf0959b5173cf01c7bb6987a5119895c76d39 /bitbake
parentd82eac804134028ece749928aa2d83096b7aec96 (diff)
downloadopenembedded-core-contrib-8d80483e2f0f755a61087be1dffaf595fbc467fd.tar.gz
bitbake: bitbake-layers: print the recipe's depends that crosses a layer boundary
Figure out the dependency between recipes that crosses a layer boundary * Introduction: - For the .bb file, we need check the following depends: > Check the DEPENDS, RDEPENDS and inherits according to the cooker_data. > The cooker_data doesn't have the info about "require/include xxx", so we need check them manually. - For the .bbclass, .inc and .conf file, we can't get their file depends from the cooker_data, we need check them manually. * Usage: $ bitbake-layer show-cross-depends I don't like the name "show-cross-depends", figure-out-cross-depends might be better, but most of the commands are "show-xxx" for bitbake-layers. * Output: (snipped) /work/poky/meta/recipes-support/libusb/libusb-compat_0.1.4.bb inherits /work/poky/meta-yocto/classes/poky-sanity.bbclass /work/poky/meta-intel/meta-cedartrail/recipes-cdv-media/images/core-image-cdv-media.bb requires /work/poky/meta/recipes-sato/images/core-image-sato.bb /work/poky/meta-yocto/recipes-core/tiny-init/tiny-init.bb RDEPENDS /work/poky/meta/recipes-core/busybox/busybox_1.20.2.bb /work/poky/meta-intel/common/recipes-bsp/amt/lms_7.1.20.bb DEPENDS /work/poky/meta/recipes-devtools/autoconf/autoconf_2.69.bb /work/poky/meta/classes/distrodata.bbclass includes /work/poky/meta-yocto/conf/distro/include/package_regex.inc /work/poky/meta-intel/meta-sys940x/conf/machine/sys940x.conf requires /work/poky/meta/conf/machine/include/tune-atom.inc [YOCTO #3387] (Bitbake rev: 100502ef722bf19b6c125a5e017f31686ad18421) Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rwxr-xr-xbitbake/bin/bitbake-layers133
1 files changed, 133 insertions, 0 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers
index 956e7a978c..774ce2db22 100755
--- a/bitbake/bin/bitbake-layers
+++ b/bitbake/bin/bitbake-layers
@@ -542,6 +542,139 @@ Recipes are listed with the bbappends that apply to them as subitems.
notappended.append(basename)
return appended, notappended
+ def do_show_cross_depends(self, args):
+ """figure out the dependency between recipes that crosses a layer boundary.
+
+usage: show-cross-depends
+
+Figure out the dependency between recipes that crosses a layer boundary.
+
+NOTE:
+The .bbappend file can impact the dependency.
+"""
+ self.bbhandler.prepare()
+ pkg_fn = self.bbhandler.cooker_data.pkg_fn
+ bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True))
+ self.require_re = re.compile(r"require\s+(.+)")
+ self.include_re = re.compile(r"include\s+(.+)")
+ self.inherit_re = re.compile(r"inherit\s+(.+)")
+
+ # The bb's DEPENDS and RDEPENDS
+ for f in pkg_fn:
+ f = bb.cache.Cache.virtualfn2realfn(f)[0]
+ # Get the layername that the file is in
+ layername = self.get_file_layer(f)
+
+ # The DEPENDS
+ deps = self.bbhandler.cooker_data.deps[f]
+ for pn in deps:
+ if pn in self.bbhandler.cooker_data.pkg_pn:
+ best = bb.providers.findBestProvider(pn,
+ self.bbhandler.cooker.configuration.data,
+ self.bbhandler.cooker_data,
+ self.bbhandler.cooker_data.pkg_pn)
+ self.check_cross_depends("DEPENDS", layername, f, best[3])
+
+ # The RDPENDS
+ all_rdeps = self.bbhandler.cooker_data.rundeps[f].values()
+ # Remove the duplicated or null one.
+ sorted_rdeps = {}
+ # The all_rdeps is the list in list, so we need two for loops
+ for k1 in all_rdeps:
+ for k2 in k1:
+ sorted_rdeps[k2] = 1
+ all_rdeps = sorted_rdeps.keys()
+ for rdep in all_rdeps:
+ all_p = bb.providers.getRuntimeProviders(self.bbhandler.cooker_data, rdep)
+ if all_p:
+ best = bb.providers.filterProvidersRunTime(all_p, rdep,
+ self.bbhandler.cooker.configuration.data,
+ self.bbhandler.cooker_data)[0][0]
+ self.check_cross_depends("RDEPENDS", layername, f, best)
+
+ # The inherit class
+ cls_re = re.compile('classes/')
+ if f in self.bbhandler.cooker_data.inherits:
+ inherits = self.bbhandler.cooker_data.inherits[f]
+ for cls in inherits:
+ # The inherits' format is [classes/cls, /path/to/classes/cls]
+ # ignore the classes/cls.
+ if not cls_re.match(cls):
+ inherit_layername = self.get_file_layer(cls)
+ if inherit_layername != layername:
+ logger.plain("%s inherits %s" % (f, cls))
+
+ # The 'require/include xxx' in the bb file
+ pv_re = re.compile(r"\${PV}")
+ fnfile = open(f, 'r')
+ line = fnfile.readline()
+ while line:
+ m, keyword = self.match_require_include(line)
+ # Found the 'require/include xxxx'
+ if m:
+ needed_file = m.group(1)
+ # Replace the ${PV} with the real PV
+ if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr:
+ pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1]
+ needed_file = re.sub(r"\${PV}", pv, needed_file)
+ self.print_cross_files(bbpath, keyword, layername, f, needed_file)
+ line = fnfile.readline()
+ fnfile.close()
+
+ # The "require/include xxx" in conf/machine/*.conf, .inc and .bbclass
+ conf_re = re.compile(".*/conf/machine/[^\/]*\.conf$")
+ inc_re = re.compile(".*\.inc$")
+ # The "inherit xxx" in .bbclass
+ bbclass_re = re.compile(".*\.bbclass$")
+ for layerdir in self.bblayers:
+ layername = self.get_layer_name(layerdir)
+ for dirpath, dirnames, filenames in os.walk(layerdir):
+ for name in filenames:
+ f = os.path.join(dirpath, name)
+ s = conf_re.match(f) or inc_re.match(f) or bbclass_re.match(f)
+ if s:
+ ffile = open(f, 'r')
+ line = ffile.readline()
+ while line:
+ m, keyword = self.match_require_include(line)
+ # Only bbclass has the "inherit xxx" here.
+ bbclass=""
+ if not m and f.endswith(".bbclass"):
+ m, keyword = self.match_inherit(line)
+ bbclass=".bbclass"
+ # Find a 'require/include xxxx'
+ if m:
+ self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass)
+ line = ffile.readline()
+ ffile.close()
+
+ def print_cross_files(self, bbpath, keyword, layername, f, needed_filename):
+ """Print the depends that crosses a layer boundary"""
+ needed_file = bb.utils.which(bbpath, needed_filename)
+ if needed_file:
+ # Which layer is this file from
+ needed_layername = self.get_file_layer(needed_file)
+ if needed_layername != layername:
+ logger.plain("%s %s %s" %(f, keyword, needed_file))
+ def match_inherit(self, line):
+ """Match the inherit xxx line"""
+ return (self.inherit_re.match(line), "inherits")
+
+ def match_require_include(self, line):
+ """Match the require/include xxx line"""
+ m = self.require_re.match(line)
+ keyword = "requires"
+ if not m:
+ m = self.include_re.match(line)
+ keyword = "includes"
+ return (m, keyword)
+
+ def check_cross_depends(self, keyword, layername, f, needed_file):
+ """Print the DEPENDS/RDEPENDS file that crosses a layer boundary"""
+ best_realfn = bb.cache.Cache.virtualfn2realfn(needed_file)[0]
+ needed_layername = self.get_file_layer(best_realfn)
+ if needed_layername != layername:
+ logger.plain("%s %s %s" % (f, keyword, best_realfn))
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]) or 0)