From c527fd1f14c27855a37f2e8ac5346ce8d940ced2 Mon Sep 17 00:00:00 2001 From: Tudor Florea Date: Thu, 16 Oct 2014 03:05:19 +0200 Subject: initial commit for Enea Linux 4.0-140929 Migrated from the internal git server on the daisy-enea-point-release branch Signed-off-by: Tudor Florea --- bitbake/bin/bitbake-layers | 726 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 726 insertions(+) create mode 100755 bitbake/bin/bitbake-layers (limited to 'bitbake/bin/bitbake-layers') diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers new file mode 100755 index 0000000000..2a7f82998b --- /dev/null +++ b/bitbake/bin/bitbake-layers @@ -0,0 +1,726 @@ +#!/usr/bin/env python + +# This script has subcommands which operate against your bitbake layers, either +# displaying useful information, or acting against them. +# See the help output for details on available commands. + +# Copyright (C) 2011 Mentor Graphics Corporation +# Copyright (C) 2012 Intel Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import cmd +import logging +import os +import sys +import fnmatch +from collections import defaultdict +import re + +bindir = os.path.dirname(__file__) +topdir = os.path.dirname(bindir) +sys.path[0:0] = [os.path.join(topdir, 'lib')] + +import bb.cache +import bb.cooker +import bb.providers +import bb.utils +import bb.tinfoil + + +logger = logging.getLogger('BitBake') + + +def main(args): + cmds = Commands() + if args: + # Allow user to specify e.g. show-layers instead of show_layers + args = [args[0].replace('-', '_')] + args[1:] + cmds.onecmd(' '.join(args)) + else: + cmds.do_help('') + return cmds.returncode + + +class Commands(cmd.Cmd): + def __init__(self): + self.bbhandler = None + self.returncode = 0 + self.bblayers = [] + cmd.Cmd.__init__(self) + + def init_bbhandler(self, config_only = False): + if not self.bbhandler: + self.bbhandler = bb.tinfoil.Tinfoil() + self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() + self.bbhandler.prepare(config_only) + + def default(self, line): + """Handle unrecognised commands""" + sys.stderr.write("Unrecognised command or option\n") + self.do_help('') + + def do_help(self, topic): + """display general help or help on a specified command""" + if topic: + sys.stdout.write('%s: ' % topic) + cmd.Cmd.do_help(self, topic.replace('-', '_')) + else: + sys.stdout.write("usage: bitbake-layers [arguments]\n\n") + sys.stdout.write("Available commands:\n") + procnames = list(set(self.get_names())) + for procname in procnames: + if procname[:3] == 'do_': + sys.stdout.write(" %s\n" % procname[3:].replace('_', '-')) + doc = getattr(self, procname).__doc__ + if doc: + sys.stdout.write(" %s\n" % doc.splitlines()[0]) + + def do_show_layers(self, args): + """show current configured layers""" + self.init_bbhandler(config_only = True) + logger.plain("%s %s %s" % ("layer".ljust(20), "path".ljust(40), "priority")) + logger.plain('=' * 74) + for layerdir in self.bblayers: + layername = self.get_layer_name(layerdir) + layerpri = 0 + for layer, _, regex, pri in self.bbhandler.cooker.recipecache.bbfile_config_priorities: + if regex.match(os.path.join(layerdir, 'test')): + layerpri = pri + break + + logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) + + + def version_str(self, pe, pv, pr = None): + verstr = "%s" % pv + if pr: + verstr = "%s-%s" % (verstr, pr) + if pe: + verstr = "%s:%s" % (pe, verstr) + return verstr + + + def do_show_overlayed(self, args): + """list overlayed recipes (where the same recipe exists in another layer) + +usage: show-overlayed [-f] [-s] + +Lists the names of overlayed recipes and the available versions in each +layer, with the preferred version first. Note that skipped recipes that +are overlayed will also be listed, with a " (skipped)" suffix. + +Options: + -f instead of the default formatting, list filenames of higher priority + recipes with the ones they overlay indented underneath + -s only list overlayed recipes where the version is the same +""" + self.init_bbhandler() + + show_filenames = False + show_same_ver_only = False + for arg in args.split(): + if arg == '-f': + show_filenames = True + elif arg == '-s': + show_same_ver_only = True + else: + sys.stderr.write("show-overlayed: invalid option %s\n" % arg) + self.do_help('') + return + + items_listed = self.list_recipes('Overlayed recipes', None, True, show_same_ver_only, show_filenames, True) + + # Check for overlayed .bbclass files + classes = defaultdict(list) + for layerdir in self.bblayers: + classdir = os.path.join(layerdir, 'classes') + if os.path.exists(classdir): + for classfile in os.listdir(classdir): + if os.path.splitext(classfile)[1] == '.bbclass': + classes[classfile].append(classdir) + + # Locating classes and other files is a bit more complicated than recipes - + # layer priority is not a factor; instead BitBake uses the first matching + # file in BBPATH, which is manipulated directly by each layer's + # conf/layer.conf in turn, thus the order of layers in bblayers.conf is a + # factor - however, each layer.conf is free to either prepend or append to + # BBPATH (or indeed do crazy stuff with it). Thus the order in BBPATH might + # not be exactly the order present in bblayers.conf either. + bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True)) + overlayed_class_found = False + for (classfile, classdirs) in classes.items(): + if len(classdirs) > 1: + if not overlayed_class_found: + logger.plain('=== Overlayed classes ===') + overlayed_class_found = True + + mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile)) + if show_filenames: + logger.plain('%s' % mainfile) + else: + # We effectively have to guess the layer here + logger.plain('%s:' % classfile) + mainlayername = '?' + for layerdir in self.bblayers: + classdir = os.path.join(layerdir, 'classes') + if mainfile.startswith(classdir): + mainlayername = self.get_layer_name(layerdir) + logger.plain(' %s' % mainlayername) + for classdir in classdirs: + fullpath = os.path.join(classdir, classfile) + if fullpath != mainfile: + if show_filenames: + print(' %s' % fullpath) + else: + print(' %s' % self.get_layer_name(os.path.dirname(classdir))) + + if overlayed_class_found: + items_listed = True; + + if not items_listed: + logger.plain('No overlayed files found.') + + + def do_show_recipes(self, args): + """list available recipes, showing the layer they are provided by + +usage: show-recipes [-f] [-m] [pnspec] + +Lists the names of overlayed recipes and the available versions in each +layer, with the preferred version first. Optionally you may specify +pnspec to match a specified recipe name (supports wildcards). Note that +skipped recipes will also be listed, with a " (skipped)" suffix. + +Options: + -f instead of the default formatting, list filenames of higher priority + recipes with other available recipes indented underneath + -m only list where multiple recipes (in the same layer or different + layers) exist for the same recipe name +""" + self.init_bbhandler() + + show_filenames = False + show_multi_provider_only = False + pnspec = None + title = 'Available recipes:' + for arg in args.split(): + if arg == '-f': + show_filenames = True + elif arg == '-m': + show_multi_provider_only = True + elif not arg.startswith('-'): + pnspec = arg + title = 'Available recipes matching %s:' % pnspec + else: + sys.stderr.write("show-recipes: invalid option %s\n" % arg) + self.do_help('') + return + self.list_recipes(title, pnspec, False, False, show_filenames, show_multi_provider_only) + + + def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): + pkg_pn = self.bbhandler.cooker.recipecache.pkg_pn + (latest_versions, preferred_versions) = bb.providers.findProviders(self.bbhandler.config_data, self.bbhandler.cooker.recipecache, pkg_pn) + allproviders = bb.providers.allProviders(self.bbhandler.cooker.recipecache) + + # Ensure we list skipped recipes + # We are largely guessing about PN, PV and the preferred version here, + # but we have no choice since skipped recipes are not fully parsed + skiplist = self.bbhandler.cooker.skiplist.keys() + skiplist.sort( key=lambda fileitem: self.bbhandler.cooker.collection.calc_bbfile_priority(fileitem) ) + skiplist.reverse() + for fn in skiplist: + recipe_parts = os.path.splitext(os.path.basename(fn))[0].split('_') + p = recipe_parts[0] + if len(recipe_parts) > 1: + ver = (None, recipe_parts[1], None) + else: + ver = (None, 'unknown', None) + allproviders[p].append((ver, fn)) + if not p in pkg_pn: + pkg_pn[p] = 'dummy' + preferred_versions[p] = (ver, fn) + + def print_item(f, pn, ver, layer, ispref): + if f in skiplist: + skipped = ' (skipped)' + else: + skipped = '' + if show_filenames: + if ispref: + logger.plain("%s%s", f, skipped) + else: + logger.plain(" %s%s", f, skipped) + else: + if ispref: + logger.plain("%s:", pn) + logger.plain(" %s %s%s", layer.ljust(20), ver, skipped) + + preffiles = [] + items_listed = False + for p in sorted(pkg_pn): + if pnspec: + if not fnmatch.fnmatch(p, pnspec): + continue + + if len(allproviders[p]) > 1 or not show_multi_provider_only: + pref = preferred_versions[p] + preffile = bb.cache.Cache.virtualfn2realfn(pref[1])[0] + if preffile not in preffiles: + preflayer = self.get_file_layer(preffile) + multilayer = False + same_ver = True + provs = [] + for prov in allproviders[p]: + provfile = bb.cache.Cache.virtualfn2realfn(prov[1])[0] + provlayer = self.get_file_layer(provfile) + provs.append((provfile, provlayer, prov[0])) + if provlayer != preflayer: + multilayer = True + if prov[0] != pref[0]: + same_ver = False + + if (multilayer or not show_overlayed_only) and (same_ver or not show_same_ver_only): + if not items_listed: + logger.plain('=== %s ===' % title) + items_listed = True + print_item(preffile, p, self.version_str(pref[0][0], pref[0][1]), preflayer, True) + for (provfile, provlayer, provver) in provs: + if provfile != preffile: + print_item(provfile, p, self.version_str(provver[0], provver[1]), provlayer, False) + # Ensure we don't show two entries for BBCLASSEXTENDed recipes + preffiles.append(preffile) + + return items_listed + + + def do_flatten(self, args): + """flattens layer configuration into a separate output directory. + +usage: flatten [layer1 layer2 [layer3]...] + +Takes the specified layers (or all layers in the current layer +configuration if none are specified) and builds a "flattened" directory +containing the contents of all layers, with any overlayed recipes removed +and bbappends appended to the corresponding recipes. Note that some manual +cleanup may still be necessary afterwards, in particular: + +* where non-recipe files (such as patches) are overwritten (the flatten + command will show a warning for these) +* where anything beyond the normal layer setup has been added to + layer.conf (only the lowest priority number layer's layer.conf is used) +* overridden/appended items from bbappends will need to be tidied up +* when the flattened layers do not have the same directory structure (the + flatten command should show a warning when this will cause a problem) + +Warning: if you flatten several layers where another layer is intended to +be used "inbetween" them (in layer priority order) such that recipes / +bbappends in the layers interact, and then attempt to use the new output +layer together with that other layer, you may no longer get the same +build results (as the layer priority order has effectively changed). +""" + arglist = args.split() + if len(arglist) < 1: + logger.error('Please specify an output directory') + self.do_help('flatten') + return + + if len(arglist) == 2: + logger.error('If you specify layers to flatten you must specify at least two') + self.do_help('flatten') + return + + outputdir = arglist[-1] + if os.path.exists(outputdir) and os.listdir(outputdir): + logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) + return + + self.init_bbhandler() + layers = self.bblayers + if len(arglist) > 2: + layernames = arglist[:-1] + found_layernames = [] + found_layerdirs = [] + for layerdir in layers: + layername = self.get_layer_name(layerdir) + if layername in layernames: + found_layerdirs.append(layerdir) + found_layernames.append(layername) + + for layername in layernames: + if not layername in found_layernames: + logger.error('Unable to find layer %s in current configuration, please run "%s show-layers" to list configured layers' % (layername, os.path.basename(sys.argv[0]))) + return + layers = found_layerdirs + else: + layernames = [] + + # Ensure a specified path matches our list of layers + def layer_path_match(path): + for layerdir in layers: + if path.startswith(os.path.join(layerdir, '')): + return layerdir + return None + + appended_recipes = [] + for layer in layers: + overlayed = [] + for f in self.bbhandler.cooker.collection.overlayed.iterkeys(): + for of in self.bbhandler.cooker.collection.overlayed[f]: + if of.startswith(layer): + overlayed.append(of) + + logger.plain('Copying files from %s...' % layer ) + for root, dirs, files in os.walk(layer): + for f1 in files: + f1full = os.sep.join([root, f1]) + if f1full in overlayed: + logger.plain(' Skipping overlayed file %s' % f1full ) + else: + ext = os.path.splitext(f1)[1] + if ext != '.bbappend': + fdest = f1full[len(layer):] + fdest = os.path.normpath(os.sep.join([outputdir,fdest])) + bb.utils.mkdirhier(os.path.dirname(fdest)) + if os.path.exists(fdest): + if f1 == 'layer.conf' and root.endswith('/conf'): + logger.plain(' Skipping layer config file %s' % f1full ) + continue + else: + logger.warn('Overwriting file %s', fdest) + bb.utils.copyfile(f1full, fdest) + if ext == '.bb': + if f1 in self.bbhandler.cooker.collection.appendlist: + appends = self.bbhandler.cooker.collection.appendlist[f1] + if appends: + logger.plain(' Applying appends to %s' % fdest ) + for appendname in appends: + if layer_path_match(appendname): + self.apply_append(appendname, fdest) + appended_recipes.append(f1) + + # Take care of when some layers are excluded and yet we have included bbappends for those recipes + for recipename in self.bbhandler.cooker.collection.appendlist.iterkeys(): + if recipename not in appended_recipes: + appends = self.bbhandler.cooker.collection.appendlist[recipename] + first_append = None + for appendname in appends: + layer = layer_path_match(appendname) + if layer: + if first_append: + self.apply_append(appendname, first_append) + else: + fdest = appendname[len(layer):] + fdest = os.path.normpath(os.sep.join([outputdir,fdest])) + bb.utils.mkdirhier(os.path.dirname(fdest)) + bb.utils.copyfile(appendname, fdest) + first_append = fdest + + # Get the regex for the first layer in our list (which is where the conf/layer.conf file will + # have come from) + first_regex = None + layerdir = layers[0] + for layername, pattern, regex, _ in self.bbhandler.cooker.recipecache.bbfile_config_priorities: + if regex.match(os.path.join(layerdir, 'test')): + first_regex = regex + break + + if first_regex: + # Find the BBFILES entries that match (which will have come from this conf/layer.conf file) + bbfiles = str(self.bbhandler.config_data.getVar('BBFILES', True)).split() + bbfiles_layer = [] + for item in bbfiles: + if first_regex.match(item): + newpath = os.path.join(outputdir, item[len(layerdir)+1:]) + bbfiles_layer.append(newpath) + + if bbfiles_layer: + # Check that all important layer files match BBFILES + for root, dirs, files in os.walk(outputdir): + for f1 in files: + ext = os.path.splitext(f1)[1] + if ext in ['.bb', '.bbappend']: + f1full = os.sep.join([root, f1]) + entry_found = False + for item in bbfiles_layer: + if fnmatch.fnmatch(f1full, item): + entry_found = True + break + if not entry_found: + logger.warning("File %s does not match the flattened layer's BBFILES setting, you may need to edit conf/layer.conf or move the file elsewhere" % f1full) + + def get_file_layer(self, filename): + for layer, _, regex, _ in self.bbhandler.cooker.recipecache.bbfile_config_priorities: + if regex.match(filename): + for layerdir in self.bblayers: + if regex.match(os.path.join(layerdir, 'test')) and re.match(layerdir, filename): + return self.get_layer_name(layerdir) + return "?" + + def get_file_layerdir(self, filename): + for layer, _, regex, _ in self.bbhandler.cooker.recipecache.bbfile_config_priorities: + if regex.match(filename): + for layerdir in self.bblayers: + if regex.match(os.path.join(layerdir, 'test')) and re.match(layerdir, filename): + return layerdir + return "?" + + def remove_layer_prefix(self, f): + """Remove the layer_dir prefix, e.g., f = /path/to/layer_dir/foo/blah, the + return value will be: layer_dir/foo/blah""" + f_layerdir = self.get_file_layerdir(f) + prefix = os.path.join(os.path.dirname(f_layerdir), '') + return f[len(prefix):] if f.startswith(prefix) else f + + def get_layer_name(self, layerdir): + return os.path.basename(layerdir.rstrip(os.sep)) + + def apply_append(self, appendname, recipename): + appendfile = open(appendname, 'r') + recipefile = open(recipename, 'a') + recipefile.write('\n') + recipefile.write('##### bbappended from %s #####\n' % self.get_file_layer(appendname)) + recipefile.writelines(appendfile.readlines()) + recipefile.close() + appendfile.close() + + def do_show_appends(self, args): + """list bbappend files and recipe files they apply to + +usage: show-appends + +Recipes are listed with the bbappends that apply to them as subitems. +""" + self.init_bbhandler() + if not self.bbhandler.cooker.collection.appendlist: + logger.plain('No append files found') + return + + logger.plain('=== Appended recipes ===') + + pnlist = list(self.bbhandler.cooker_data.pkg_pn.keys()) + pnlist.sort() + for pn in pnlist: + self.show_appends_for_pn(pn) + + self.show_appends_for_skipped() + + def show_appends_for_pn(self, pn): + filenames = self.bbhandler.cooker_data.pkg_pn[pn] + + best = bb.providers.findBestProvider(pn, + self.bbhandler.config_data, + self.bbhandler.cooker_data, + self.bbhandler.cooker_data.pkg_pn) + best_filename = os.path.basename(best[3]) + + self.show_appends_output(filenames, best_filename) + + def show_appends_for_skipped(self): + filenames = [os.path.basename(f) + for f in self.bbhandler.cooker.skiplist.iterkeys()] + self.show_appends_output(filenames, None, " (skipped)") + + def show_appends_output(self, filenames, best_filename, name_suffix = ''): + appended, missing = self.get_appends_for_files(filenames) + if appended: + for basename, appends in appended: + logger.plain('%s%s:', basename, name_suffix) + for append in appends: + logger.plain(' %s', append) + + if best_filename: + if best_filename in missing: + logger.warn('%s: missing append for preferred version', + best_filename) + self.returncode |= 1 + + + def get_appends_for_files(self, filenames): + appended, notappended = [], [] + for filename in filenames: + _, cls = bb.cache.Cache.virtualfn2realfn(filename) + if cls: + continue + + basename = os.path.basename(filename) + appends = self.bbhandler.cooker.collection.appendlist.get(basename) + if appends: + appended.append((basename, list(appends))) + else: + 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 [-f] + +Figure out the dependency between recipes that crosses a layer boundary. + +Options: + -f show full file path + +NOTE: +The .bbappend file can impact the dependency. +""" + self.init_bbhandler() + + show_filenames = False + for arg in args.split(): + if arg == '-f': + show_filenames = True + else: + sys.stderr.write("show-cross-depends: invalid option %s\n" % arg) + self.do_help('') + return + + 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.config_data, + self.bbhandler.cooker_data, + self.bbhandler.cooker_data.pkg_pn) + self.check_cross_depends("DEPENDS", layername, f, best[3], show_filenames) + + # 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.config_data, + self.bbhandler.cooker_data)[0][0] + self.check_cross_depends("RDEPENDS", layername, f, best, show_filenames) + + # 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: + if not show_filenames: + f_short = self.remove_layer_prefix(f) + cls = self.remove_layer_prefix(cls) + else: + f_short = f + logger.plain("%s inherits %s" % (f_short, 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, show_filenames) + 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, show_filenames) + line = ffile.readline() + ffile.close() + + def print_cross_files(self, bbpath, keyword, layername, f, needed_filename, show_filenames): + """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: + if not show_filenames: + f = self.remove_layer_prefix(f) + needed_file = self.remove_layer_prefix(needed_file) + 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, show_filenames): + """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: + if not show_filenames: + f = self.remove_layer_prefix(f) + best_realfn = self.remove_layer_prefix(best_realfn) + + logger.plain("%s %s %s" % (f, keyword, best_realfn)) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:]) or 0) -- cgit v1.2.3-54-g00ecf