diff options
| -rwxr-xr-x | bitbake/bin/bitbake-layers | 261 |
1 files changed, 110 insertions, 151 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers index 98794981a0..2622bc0927 100755 --- a/bitbake/bin/bitbake-layers +++ b/bitbake/bin/bitbake-layers | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | # See the help output for details on available commands. | 5 | # See the help output for details on available commands. |
| 6 | 6 | ||
| 7 | # Copyright (C) 2011 Mentor Graphics Corporation | 7 | # Copyright (C) 2011 Mentor Graphics Corporation |
| 8 | # Copyright (C) 2012 Intel Corporation | 8 | # Copyright (C) 2011-2015 Intel Corporation |
| 9 | # | 9 | # |
| 10 | # This program is free software; you can redistribute it and/or modify | 10 | # This program is free software; you can redistribute it and/or modify |
| 11 | # it under the terms of the GNU General Public License version 2 as | 11 | # it under the terms of the GNU General Public License version 2 as |
| @@ -20,12 +20,12 @@ | |||
| 20 | # with this program; if not, write to the Free Software Foundation, Inc., | 20 | # with this program; if not, write to the Free Software Foundation, Inc., |
| 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 22 | 22 | ||
| 23 | import cmd | ||
| 24 | import logging | 23 | import logging |
| 25 | import os | 24 | import os |
| 26 | import sys | 25 | import sys |
| 27 | import fnmatch | 26 | import fnmatch |
| 28 | from collections import defaultdict | 27 | from collections import defaultdict |
| 28 | import argparse | ||
| 29 | import re | 29 | import re |
| 30 | 30 | ||
| 31 | bindir = os.path.dirname(__file__) | 31 | bindir = os.path.dirname(__file__) |
| @@ -42,23 +42,11 @@ import bb.tinfoil | |||
| 42 | logger = logging.getLogger('BitBake') | 42 | logger = logging.getLogger('BitBake') |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | def main(args): | ||
| 46 | cmds = Commands() | ||
| 47 | if args: | ||
| 48 | # Allow user to specify e.g. show-layers instead of show_layers | ||
| 49 | args = [args[0].replace('-', '_')] + args[1:] | ||
| 50 | cmds.onecmd(' '.join(args)) | ||
| 51 | else: | ||
| 52 | cmds.do_help('') | ||
| 53 | return cmds.returncode | ||
| 54 | |||
| 55 | 45 | ||
| 56 | class Commands(cmd.Cmd): | 46 | class Commands(): |
| 57 | def __init__(self): | 47 | def __init__(self): |
| 58 | self.bbhandler = None | 48 | self.bbhandler = None |
| 59 | self.returncode = 0 | ||
| 60 | self.bblayers = [] | 49 | self.bblayers = [] |
| 61 | cmd.Cmd.__init__(self) | ||
| 62 | 50 | ||
| 63 | def init_bbhandler(self, config_only = False): | 51 | def init_bbhandler(self, config_only = False): |
| 64 | if not self.bbhandler: | 52 | if not self.bbhandler: |
| @@ -66,27 +54,6 @@ class Commands(cmd.Cmd): | |||
| 66 | self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() | 54 | self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() |
| 67 | self.bbhandler.prepare(config_only) | 55 | self.bbhandler.prepare(config_only) |
| 68 | 56 | ||
| 69 | def default(self, line): | ||
| 70 | """Handle unrecognised commands""" | ||
| 71 | sys.stderr.write("Unrecognised command or option\n") | ||
| 72 | self.do_help('') | ||
| 73 | |||
| 74 | def do_help(self, topic): | ||
| 75 | """display general help or help on a specified command""" | ||
| 76 | if topic: | ||
| 77 | sys.stdout.write('%s: ' % topic) | ||
| 78 | cmd.Cmd.do_help(self, topic.replace('-', '_')) | ||
| 79 | else: | ||
| 80 | sys.stdout.write("usage: bitbake-layers <command> [arguments]\n\n") | ||
| 81 | sys.stdout.write("Available commands:\n") | ||
| 82 | procnames = list(set(self.get_names())) | ||
| 83 | for procname in procnames: | ||
| 84 | if procname[:3] == 'do_': | ||
| 85 | sys.stdout.write(" %s\n" % procname[3:].replace('_', '-')) | ||
| 86 | doc = getattr(self, procname).__doc__ | ||
| 87 | if doc: | ||
| 88 | sys.stdout.write(" %s\n" % doc.splitlines()[0]) | ||
| 89 | |||
| 90 | def do_show_layers(self, args): | 57 | def do_show_layers(self, args): |
| 91 | """show current configured layers""" | 58 | """show current configured layers""" |
| 92 | self.init_bbhandler(config_only = True) | 59 | self.init_bbhandler(config_only = True) |
| @@ -103,29 +70,25 @@ class Commands(cmd.Cmd): | |||
| 103 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) | 70 | logger.plain("%s %s %d" % (layername.ljust(20), layerdir.ljust(40), layerpri)) |
| 104 | 71 | ||
| 105 | 72 | ||
| 106 | def do_add_layer(self, dirname): | 73 | def do_add_layer(self, args): |
| 107 | """Add a layer to bblayers.conf | 74 | """Add a layer to bblayers.conf |
| 108 | 75 | ||
| 109 | usage: add-layer <layerdir> | 76 | Adds the specified layer to bblayers.conf |
| 110 | """ | 77 | """ |
| 111 | if not dirname: | 78 | layerdir = os.path.abspath(args.layerdir) |
| 112 | sys.stderr.write("Please specify the layer directory to add\n") | ||
| 113 | return | ||
| 114 | |||
| 115 | layerdir = os.path.abspath(dirname) | ||
| 116 | if not os.path.exists(layerdir): | 79 | if not os.path.exists(layerdir): |
| 117 | sys.stderr.write("Specified layer directory doesn't exist\n") | 80 | sys.stderr.write("Specified layer directory doesn't exist\n") |
| 118 | return | 81 | return 1 |
| 119 | 82 | ||
| 120 | layer_conf = os.path.join(layerdir, 'conf', 'layer.conf') | 83 | layer_conf = os.path.join(layerdir, 'conf', 'layer.conf') |
| 121 | if not os.path.exists(layer_conf): | 84 | if not os.path.exists(layer_conf): |
| 122 | sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n") | 85 | sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n") |
| 123 | return | 86 | return 1 |
| 124 | 87 | ||
| 125 | bblayers_conf = os.path.join('conf', 'bblayers.conf') | 88 | bblayers_conf = os.path.join('conf', 'bblayers.conf') |
| 126 | if not os.path.exists(bblayers_conf): | 89 | if not os.path.exists(bblayers_conf): |
| 127 | sys.stderr.write("Unable to find bblayers.conf\n") | 90 | sys.stderr.write("Unable to find bblayers.conf\n") |
| 128 | return | 91 | return 1 |
| 129 | 92 | ||
| 130 | (notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None) | 93 | (notadded, _) = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None) |
| 131 | if notadded: | 94 | if notadded: |
| @@ -133,28 +96,25 @@ usage: add-layer <layerdir> | |||
| 133 | sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item) | 96 | sys.stderr.write("Specified layer %s is already in BBLAYERS\n" % item) |
| 134 | 97 | ||
| 135 | 98 | ||
| 136 | def do_remove_layer(self, dirname): | 99 | def do_remove_layer(self, args): |
| 137 | """Remove a layer from bblayers.conf | 100 | """Remove a layer from bblayers.conf |
| 138 | 101 | ||
| 139 | usage: remove-layer <layerdir> | 102 | Removes the specified layer from bblayers.conf |
| 140 | """ | 103 | """ |
| 141 | if not dirname: | ||
| 142 | sys.stderr.write("Please specify the layer directory to remove\n") | ||
| 143 | return | ||
| 144 | |||
| 145 | bblayers_conf = os.path.join('conf', 'bblayers.conf') | 104 | bblayers_conf = os.path.join('conf', 'bblayers.conf') |
| 146 | if not os.path.exists(bblayers_conf): | 105 | if not os.path.exists(bblayers_conf): |
| 147 | sys.stderr.write("Unable to find bblayers.conf\n") | 106 | sys.stderr.write("Unable to find bblayers.conf\n") |
| 148 | return | 107 | return 1 |
| 149 | 108 | ||
| 150 | if dirname.startswith('*'): | 109 | if args.layerdir.startswith('*'): |
| 151 | layerdir = dirname | 110 | layerdir = dirname |
| 152 | else: | 111 | else: |
| 153 | layerdir = os.path.abspath(dirname) | 112 | layerdir = os.path.abspath(args.layerdir) |
| 154 | (_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir) | 113 | (_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir) |
| 155 | if notremoved: | 114 | if notremoved: |
| 156 | for item in notremoved: | 115 | for item in notremoved: |
| 157 | sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item) | 116 | sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item) |
| 117 | return 1 | ||
| 158 | 118 | ||
| 159 | 119 | ||
| 160 | def version_str(self, pe, pv, pr = None): | 120 | def version_str(self, pe, pv, pr = None): |
| @@ -169,32 +129,13 @@ usage: remove-layer <layerdir> | |||
| 169 | def do_show_overlayed(self, args): | 129 | def do_show_overlayed(self, args): |
| 170 | """list overlayed recipes (where the same recipe exists in another layer) | 130 | """list overlayed recipes (where the same recipe exists in another layer) |
| 171 | 131 | ||
| 172 | usage: show-overlayed [-f] [-s] | ||
| 173 | |||
| 174 | Lists the names of overlayed recipes and the available versions in each | 132 | Lists the names of overlayed recipes and the available versions in each |
| 175 | layer, with the preferred version first. Note that skipped recipes that | 133 | layer, with the preferred version first. Note that skipped recipes that |
| 176 | are overlayed will also be listed, with a " (skipped)" suffix. | 134 | are overlayed will also be listed, with a " (skipped)" suffix. |
| 177 | |||
| 178 | Options: | ||
| 179 | -f instead of the default formatting, list filenames of higher priority | ||
| 180 | recipes with the ones they overlay indented underneath | ||
| 181 | -s only list overlayed recipes where the version is the same | ||
| 182 | """ | 135 | """ |
| 183 | self.init_bbhandler() | 136 | self.init_bbhandler() |
| 184 | 137 | ||
| 185 | show_filenames = False | 138 | items_listed = self.list_recipes('Overlayed recipes', None, True, args.same_version, args.filenames, True) |
| 186 | show_same_ver_only = False | ||
| 187 | for arg in args.split(): | ||
| 188 | if arg == '-f': | ||
| 189 | show_filenames = True | ||
| 190 | elif arg == '-s': | ||
| 191 | show_same_ver_only = True | ||
| 192 | else: | ||
| 193 | sys.stderr.write("show-overlayed: invalid option %s\n" % arg) | ||
| 194 | self.do_help('') | ||
| 195 | return | ||
| 196 | |||
| 197 | items_listed = self.list_recipes('Overlayed recipes', None, True, show_same_ver_only, show_filenames, True) | ||
| 198 | 139 | ||
| 199 | # Check for overlayed .bbclass files | 140 | # Check for overlayed .bbclass files |
| 200 | classes = defaultdict(list) | 141 | classes = defaultdict(list) |
| @@ -221,7 +162,7 @@ Options: | |||
| 221 | overlayed_class_found = True | 162 | overlayed_class_found = True |
| 222 | 163 | ||
| 223 | mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile)) | 164 | mainfile = bb.utils.which(bbpath, os.path.join('classes', classfile)) |
| 224 | if show_filenames: | 165 | if args.filenames: |
| 225 | logger.plain('%s' % mainfile) | 166 | logger.plain('%s' % mainfile) |
| 226 | else: | 167 | else: |
| 227 | # We effectively have to guess the layer here | 168 | # We effectively have to guess the layer here |
| @@ -235,7 +176,7 @@ Options: | |||
| 235 | for classdir in classdirs: | 176 | for classdir in classdirs: |
| 236 | fullpath = os.path.join(classdir, classfile) | 177 | fullpath = os.path.join(classdir, classfile) |
| 237 | if fullpath != mainfile: | 178 | if fullpath != mainfile: |
| 238 | if show_filenames: | 179 | if args.filenames: |
| 239 | print(' %s' % fullpath) | 180 | print(' %s' % fullpath) |
| 240 | else: | 181 | else: |
| 241 | print(' %s' % self.get_layer_name(os.path.dirname(classdir))) | 182 | print(' %s' % self.get_layer_name(os.path.dirname(classdir))) |
| @@ -250,38 +191,15 @@ Options: | |||
| 250 | def do_show_recipes(self, args): | 191 | def do_show_recipes(self, args): |
| 251 | """list available recipes, showing the layer they are provided by | 192 | """list available recipes, showing the layer they are provided by |
| 252 | 193 | ||
| 253 | usage: show-recipes [-f] [-m] [pnspec] | 194 | Lists the names of recipes and the available versions in each |
| 254 | |||
| 255 | Lists the names of overlayed recipes and the available versions in each | ||
| 256 | layer, with the preferred version first. Optionally you may specify | 195 | layer, with the preferred version first. Optionally you may specify |
| 257 | pnspec to match a specified recipe name (supports wildcards). Note that | 196 | pnspec to match a specified recipe name (supports wildcards). Note that |
| 258 | skipped recipes will also be listed, with a " (skipped)" suffix. | 197 | skipped recipes will also be listed, with a " (skipped)" suffix. |
| 259 | |||
| 260 | Options: | ||
| 261 | -f instead of the default formatting, list filenames of higher priority | ||
| 262 | recipes with other available recipes indented underneath | ||
| 263 | -m only list where multiple recipes (in the same layer or different | ||
| 264 | layers) exist for the same recipe name | ||
| 265 | """ | 198 | """ |
| 266 | self.init_bbhandler() | 199 | self.init_bbhandler() |
| 267 | 200 | ||
| 268 | show_filenames = False | ||
| 269 | show_multi_provider_only = False | ||
| 270 | pnspec = None | ||
| 271 | title = 'Available recipes:' | 201 | title = 'Available recipes:' |
| 272 | for arg in args.split(): | 202 | self.list_recipes(title, args.pnspec, False, False, args.filenames, args.multiple) |
| 273 | if arg == '-f': | ||
| 274 | show_filenames = True | ||
| 275 | elif arg == '-m': | ||
| 276 | show_multi_provider_only = True | ||
| 277 | elif not arg.startswith('-'): | ||
| 278 | pnspec = arg | ||
| 279 | title = 'Available recipes matching %s:' % pnspec | ||
| 280 | else: | ||
| 281 | sys.stderr.write("show-recipes: invalid option %s\n" % arg) | ||
| 282 | self.do_help('') | ||
| 283 | return | ||
| 284 | self.list_recipes(title, pnspec, False, False, show_filenames, show_multi_provider_only) | ||
| 285 | 203 | ||
| 286 | 204 | ||
| 287 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): | 205 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): |
| @@ -361,9 +279,7 @@ Options: | |||
| 361 | 279 | ||
| 362 | 280 | ||
| 363 | def do_flatten(self, args): | 281 | def do_flatten(self, args): |
| 364 | """flattens layer configuration into a separate output directory. | 282 | """flatten layer configuration into a separate output directory. |
| 365 | |||
| 366 | usage: flatten [layer1 layer2 [layer3]...] <outputdir> | ||
| 367 | 283 | ||
| 368 | Takes the specified layers (or all layers in the current layer | 284 | Takes the specified layers (or all layers in the current layer |
| 369 | configuration if none are specified) and builds a "flattened" directory | 285 | configuration if none are specified) and builds a "flattened" directory |
| @@ -385,26 +301,19 @@ bbappends in the layers interact, and then attempt to use the new output | |||
| 385 | layer together with that other layer, you may no longer get the same | 301 | layer together with that other layer, you may no longer get the same |
| 386 | build results (as the layer priority order has effectively changed). | 302 | build results (as the layer priority order has effectively changed). |
| 387 | """ | 303 | """ |
| 388 | arglist = args.split() | 304 | if len(args.layer) == 1: |
| 389 | if len(arglist) < 1: | ||
| 390 | logger.error('Please specify an output directory') | ||
| 391 | self.do_help('flatten') | ||
| 392 | return | ||
| 393 | |||
| 394 | if len(arglist) == 2: | ||
| 395 | logger.error('If you specify layers to flatten you must specify at least two') | 305 | logger.error('If you specify layers to flatten you must specify at least two') |
| 396 | self.do_help('flatten') | 306 | return 1 |
| 397 | return | ||
| 398 | 307 | ||
| 399 | outputdir = arglist[-1] | 308 | outputdir = args.outputdir |
| 400 | if os.path.exists(outputdir) and os.listdir(outputdir): | 309 | if os.path.exists(outputdir) and os.listdir(outputdir): |
| 401 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) | 310 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) |
| 402 | return | 311 | return 1 |
| 403 | 312 | ||
| 404 | self.init_bbhandler() | 313 | self.init_bbhandler() |
| 405 | layers = self.bblayers | 314 | layers = self.bblayers |
| 406 | if len(arglist) > 2: | 315 | if len(args.layer) > 2: |
| 407 | layernames = arglist[:-1] | 316 | layernames = args.layer |
| 408 | found_layernames = [] | 317 | found_layernames = [] |
| 409 | found_layerdirs = [] | 318 | found_layerdirs = [] |
| 410 | for layerdir in layers: | 319 | for layerdir in layers: |
| @@ -553,14 +462,12 @@ build results (as the layer priority order has effectively changed). | |||
| 553 | def do_show_appends(self, args): | 462 | def do_show_appends(self, args): |
| 554 | """list bbappend files and recipe files they apply to | 463 | """list bbappend files and recipe files they apply to |
| 555 | 464 | ||
| 556 | usage: show-appends | 465 | Lists recipes with the bbappends that apply to them as subitems. |
| 557 | |||
| 558 | Recipes are listed with the bbappends that apply to them as subitems. | ||
| 559 | """ | 466 | """ |
| 560 | self.init_bbhandler() | 467 | self.init_bbhandler() |
| 561 | if not self.bbhandler.cooker.collection.appendlist: | 468 | if not self.bbhandler.cooker.collection.appendlist: |
| 562 | logger.plain('No append files found') | 469 | logger.plain('No append files found') |
| 563 | return | 470 | return 0 |
| 564 | 471 | ||
| 565 | logger.plain('=== Appended recipes ===') | 472 | logger.plain('=== Appended recipes ===') |
| 566 | 473 | ||
| @@ -599,7 +506,6 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
| 599 | if best_filename in missing: | 506 | if best_filename in missing: |
| 600 | logger.warn('%s: missing append for preferred version', | 507 | logger.warn('%s: missing append for preferred version', |
| 601 | best_filename) | 508 | best_filename) |
| 602 | self.returncode |= 1 | ||
| 603 | 509 | ||
| 604 | 510 | ||
| 605 | def get_appends_for_files(self, filenames): | 511 | def get_appends_for_files(self, filenames): |
| @@ -618,29 +524,13 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
| 618 | return appended, notappended | 524 | return appended, notappended |
| 619 | 525 | ||
| 620 | def do_show_cross_depends(self, args): | 526 | def do_show_cross_depends(self, args): |
| 621 | """figure out the dependency between recipes that crosses a layer boundary. | 527 | """Show dependencies between recipes that cross layer boundaries. |
| 622 | |||
| 623 | usage: show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]] | ||
| 624 | 528 | ||
| 625 | Figure out the dependency between recipes that crosses a layer boundary. | 529 | Figure out the dependencies between recipes that cross layer boundaries. |
| 626 | 530 | ||
| 627 | Options: | 531 | NOTE: .bbappend files can impact the dependencies. |
| 628 | -f show full file path | ||
| 629 | -i ignore dependencies on items in the specified layer(s) | ||
| 630 | |||
| 631 | NOTE: | ||
| 632 | The .bbappend file can impact the dependency. | ||
| 633 | """ | 532 | """ |
| 634 | import optparse | 533 | ignore_layers = (args.ignore or '').split(',') |
| 635 | |||
| 636 | parser = optparse.OptionParser(usage="show-cross-depends [-f] [-i layer1[,layer2[,layer3...]]]") | ||
| 637 | parser.add_option("-f", "", | ||
| 638 | action="store_true", dest="show_filenames") | ||
| 639 | parser.add_option("-i", "", | ||
| 640 | action="store", dest="ignore_layers", default="") | ||
| 641 | |||
| 642 | options, args = parser.parse_args(sys.argv) | ||
| 643 | ignore_layers = options.ignore_layers.split(',') | ||
| 644 | 534 | ||
| 645 | self.init_bbhandler() | 535 | self.init_bbhandler() |
| 646 | 536 | ||
| @@ -666,7 +556,7 @@ The .bbappend file can impact the dependency. | |||
| 666 | self.bbhandler.config_data, | 556 | self.bbhandler.config_data, |
| 667 | self.bbhandler.cooker_data, | 557 | self.bbhandler.cooker_data, |
| 668 | self.bbhandler.cooker_data.pkg_pn) | 558 | self.bbhandler.cooker_data.pkg_pn) |
| 669 | self.check_cross_depends("DEPENDS", layername, f, best[3], options.show_filenames, ignore_layers) | 559 | self.check_cross_depends("DEPENDS", layername, f, best[3], args.filenames, ignore_layers) |
| 670 | 560 | ||
| 671 | # The RDPENDS | 561 | # The RDPENDS |
| 672 | all_rdeps = self.bbhandler.cooker_data.rundeps[f].values() | 562 | all_rdeps = self.bbhandler.cooker_data.rundeps[f].values() |
| @@ -686,7 +576,7 @@ The .bbappend file can impact the dependency. | |||
| 686 | best = bb.providers.filterProvidersRunTime(all_p, rdep, | 576 | best = bb.providers.filterProvidersRunTime(all_p, rdep, |
| 687 | self.bbhandler.config_data, | 577 | self.bbhandler.config_data, |
| 688 | self.bbhandler.cooker_data)[0][0] | 578 | self.bbhandler.cooker_data)[0][0] |
| 689 | self.check_cross_depends("RDEPENDS", layername, f, best, options.show_filenames, ignore_layers) | 579 | self.check_cross_depends("RDEPENDS", layername, f, best, args.filenames, ignore_layers) |
| 690 | 580 | ||
| 691 | # The RRECOMMENDS | 581 | # The RRECOMMENDS |
| 692 | all_rrecs = self.bbhandler.cooker_data.runrecs[f].values() | 582 | all_rrecs = self.bbhandler.cooker_data.runrecs[f].values() |
| @@ -706,7 +596,7 @@ The .bbappend file can impact the dependency. | |||
| 706 | best = bb.providers.filterProvidersRunTime(all_p, rrec, | 596 | best = bb.providers.filterProvidersRunTime(all_p, rrec, |
| 707 | self.bbhandler.config_data, | 597 | self.bbhandler.config_data, |
| 708 | self.bbhandler.cooker_data)[0][0] | 598 | self.bbhandler.cooker_data)[0][0] |
| 709 | self.check_cross_depends("RRECOMMENDS", layername, f, best, options.show_filenames, ignore_layers) | 599 | self.check_cross_depends("RRECOMMENDS", layername, f, best, args.filenames, ignore_layers) |
| 710 | 600 | ||
| 711 | # The inherit class | 601 | # The inherit class |
| 712 | cls_re = re.compile('classes/') | 602 | cls_re = re.compile('classes/') |
| @@ -721,7 +611,7 @@ The .bbappend file can impact the dependency. | |||
| 721 | continue | 611 | continue |
| 722 | inherit_layername = self.get_file_layer(cls) | 612 | inherit_layername = self.get_file_layer(cls) |
| 723 | if inherit_layername != layername and not inherit_layername in ignore_layers: | 613 | if inherit_layername != layername and not inherit_layername in ignore_layers: |
| 724 | if not options.show_filenames: | 614 | if not args.filenames: |
| 725 | f_short = self.remove_layer_prefix(f) | 615 | f_short = self.remove_layer_prefix(f) |
| 726 | cls = self.remove_layer_prefix(cls) | 616 | cls = self.remove_layer_prefix(cls) |
| 727 | else: | 617 | else: |
| @@ -741,7 +631,7 @@ The .bbappend file can impact the dependency. | |||
| 741 | if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr: | 631 | if pv_re.search(needed_file) and f in self.bbhandler.cooker_data.pkg_pepvpr: |
| 742 | pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1] | 632 | pv = self.bbhandler.cooker_data.pkg_pepvpr[f][1] |
| 743 | needed_file = re.sub(r"\${PV}", pv, needed_file) | 633 | needed_file = re.sub(r"\${PV}", pv, needed_file) |
| 744 | self.print_cross_files(bbpath, keyword, layername, f, needed_file, options.show_filenames, ignore_layers) | 634 | self.print_cross_files(bbpath, keyword, layername, f, needed_file, args.filenames, ignore_layers) |
| 745 | line = fnfile.readline() | 635 | line = fnfile.readline() |
| 746 | fnfile.close() | 636 | fnfile.close() |
| 747 | 637 | ||
| @@ -768,7 +658,7 @@ The .bbappend file can impact the dependency. | |||
| 768 | bbclass=".bbclass" | 658 | bbclass=".bbclass" |
| 769 | # Find a 'require/include xxxx' | 659 | # Find a 'require/include xxxx' |
| 770 | if m: | 660 | if m: |
| 771 | self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, options.show_filenames, ignore_layers) | 661 | self.print_cross_files(bbpath, keyword, layername, f, m.group(1) + bbclass, args.filenames, ignore_layers) |
| 772 | line = ffile.readline() | 662 | line = ffile.readline() |
| 773 | ffile.close() | 663 | ffile.close() |
| 774 | 664 | ||
| @@ -808,5 +698,74 @@ The .bbappend file can impact the dependency. | |||
| 808 | 698 | ||
| 809 | logger.plain("%s %s %s" % (f, keyword, best_realfn)) | 699 | logger.plain("%s %s %s" % (f, keyword, best_realfn)) |
| 810 | 700 | ||
| 811 | if __name__ == '__main__': | 701 | |
| 812 | sys.exit(main(sys.argv[1:]) or 0) | 702 | def main(): |
| 703 | |||
| 704 | cmds = Commands() | ||
| 705 | |||
| 706 | def add_command(cmdname, function, *args, **kwargs): | ||
| 707 | # Convert docstring for function to help (one-liner shown in main --help) and description (shown in subcommand --help) | ||
| 708 | docsplit = function.__doc__.splitlines() | ||
| 709 | help = docsplit[0] | ||
| 710 | if len(docsplit) > 1: | ||
| 711 | desc = '\n'.join(docsplit[1:]) | ||
| 712 | else: | ||
| 713 | desc = help | ||
| 714 | subparser = subparsers.add_parser(cmdname, *args, help=help, description=desc, formatter_class=argparse.RawTextHelpFormatter, **kwargs) | ||
| 715 | subparser.set_defaults(func=function) | ||
| 716 | return subparser | ||
| 717 | |||
| 718 | parser = argparse.ArgumentParser(description="BitBake layers utility", | ||
| 719 | epilog="Use %(prog)s <subcommand> --help to get help on a specific command") | ||
| 720 | parser.add_argument('-d', '--debug', help='Enable debug output', action='store_true') | ||
| 721 | parser.add_argument('-q', '--quiet', help='Print only errors', action='store_true') | ||
| 722 | subparsers = parser.add_subparsers(title='subcommands', metavar='<subcommand>') | ||
| 723 | |||
| 724 | parser_show_layers = add_command('show-layers', cmds.do_show_layers) | ||
| 725 | |||
| 726 | parser_add_layer = add_command('add-layer', cmds.do_add_layer) | ||
| 727 | parser_add_layer.add_argument('layerdir', help='Layer directory to add') | ||
| 728 | |||
| 729 | parser_remove_layer = add_command('remove-layer', cmds.do_remove_layer) | ||
| 730 | parser_remove_layer.add_argument('layerdir', help='Layer directory to remove (wildcards allowed, enclose in quotes to avoid shell expansion)') | ||
| 731 | parser_remove_layer.set_defaults(func=cmds.do_remove_layer) | ||
| 732 | |||
| 733 | parser_show_overlayed = add_command('show-overlayed', cmds.do_show_overlayed) | ||
| 734 | parser_show_overlayed.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true') | ||
| 735 | parser_show_overlayed.add_argument('-s', '--same-version', help='only list overlayed recipes where the version is the same', action='store_true') | ||
| 736 | |||
| 737 | parser_show_recipes = add_command('show-recipes', cmds.do_show_recipes) | ||
| 738 | parser_show_recipes.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true') | ||
| 739 | parser_show_recipes.add_argument('-m', '--multiple', help='only list where multiple recipes (in the same layer or different layers) exist for the same recipe name', action='store_true') | ||
| 740 | parser_show_recipes.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)') | ||
| 741 | |||
| 742 | parser_show_appends = add_command('show-appends', cmds.do_show_appends) | ||
| 743 | |||
| 744 | parser_flatten = add_command('flatten', cmds.do_flatten) | ||
| 745 | parser_flatten.add_argument('layer', nargs='*', help='Optional layer(s) to flatten (otherwise all are flattened)') | ||
| 746 | parser_flatten.add_argument('outputdir', help='Output directory') | ||
| 747 | |||
| 748 | parser_show_cross_depends = add_command('show-cross-depends', cmds.do_show_cross_depends) | ||
| 749 | parser_show_cross_depends.add_argument('-f', '--filenames', help='show full file path', action='store_true') | ||
| 750 | parser_show_cross_depends.add_argument('-i', '--ignore', help='ignore dependencies on items in the specified layer(s) (split multiple layer names with commas, no spaces)', metavar='LAYERNAME') | ||
| 751 | |||
| 752 | args = parser.parse_args() | ||
| 753 | |||
| 754 | if args.debug: | ||
| 755 | logger.setLevel(logging.DEBUG) | ||
| 756 | elif args.quiet: | ||
| 757 | logger.setLevel(logging.ERROR) | ||
| 758 | |||
| 759 | ret = args.func(args) | ||
| 760 | |||
| 761 | return ret | ||
| 762 | |||
| 763 | |||
| 764 | if __name__ == "__main__": | ||
| 765 | try: | ||
| 766 | ret = main() | ||
| 767 | except Exception: | ||
| 768 | ret = 1 | ||
| 769 | import traceback | ||
| 770 | traceback.print_exc(5) | ||
| 771 | sys.exit(ret) | ||
