diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2012-08-27 21:44:31 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-09-07 12:10:43 +0100 |
commit | 56a66a1fabc945cd3673786dd0e7b17eaddcd7dc (patch) | |
tree | 91a84a75ae43a5c5624c3d2d8100b229f44811ab /bitbake/bin/bitbake-layers | |
parent | e8d87846e3d9ce568cc0280bad84174e151a6610 (diff) | |
download | poky-56a66a1fabc945cd3673786dd0e7b17eaddcd7dc.tar.gz |
bitbake: tinfoil: create simple interface for bitbake-based utilities
The code to initialise BitBake within bitbake-layers should be useful
for other utilities that need to query configuration or recipe
information, so refactor it out into its own class, "Tinfoil" (to
continue with our cooking metaphor).
(Bitbake rev: e5707e3938ace47c4a8d1fa2e81583fd4dc6b95d)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/bin/bitbake-layers')
-rwxr-xr-x | bitbake/bin/bitbake-layers | 146 |
1 files changed, 47 insertions, 99 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers index f4737114d7..fa4e767acc 100755 --- a/bitbake/bin/bitbake-layers +++ b/bitbake/bin/bitbake-layers | |||
@@ -6,10 +6,22 @@ | |||
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) 2012 Intel Corporation |
9 | # | ||
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 | ||
12 | # published by the Free Software Foundation. | ||
13 | # | ||
14 | # This program is distributed in the hope that it will be useful, | ||
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | # GNU General Public License for more details. | ||
18 | # | ||
19 | # You should have received a copy of the GNU General Public License along | ||
20 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
9 | 22 | ||
10 | import cmd | 23 | import cmd |
11 | import logging | 24 | import logging |
12 | import warnings | ||
13 | import os | 25 | import os |
14 | import sys | 26 | import sys |
15 | import fnmatch | 27 | import fnmatch |
@@ -23,26 +35,14 @@ import bb.cache | |||
23 | import bb.cooker | 35 | import bb.cooker |
24 | import bb.providers | 36 | import bb.providers |
25 | import bb.utils | 37 | import bb.utils |
26 | from bb.cooker import state | 38 | import bb.tinfoil |
27 | import bb.fetch2 | ||
28 | 39 | ||
29 | 40 | ||
30 | logger = logging.getLogger('BitBake') | 41 | logger = logging.getLogger('BitBake') |
31 | 42 | ||
32 | warnings.filterwarnings("ignore", category=DeprecationWarning) | ||
33 | 43 | ||
34 | def main(args): | 44 | def main(args): |
35 | # Set up logging | 45 | cmds = Commands() |
36 | console = logging.StreamHandler(sys.stdout) | ||
37 | format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") | ||
38 | bb.msg.addDefaultlogFilter(console) | ||
39 | console.setFormatter(format) | ||
40 | logger.addHandler(console) | ||
41 | |||
42 | initialenv = os.environ.copy() | ||
43 | bb.utils.clean_environment() | ||
44 | |||
45 | cmds = Commands(initialenv) | ||
46 | if args: | 46 | if args: |
47 | # Allow user to specify e.g. show-layers instead of show_layers | 47 | # Allow user to specify e.g. show-layers instead of show_layers |
48 | args = [args[0].replace('-', '_')] + args[1:] | 48 | args = [args[0].replace('-', '_')] + args[1:] |
@@ -53,46 +53,11 @@ def main(args): | |||
53 | 53 | ||
54 | 54 | ||
55 | class Commands(cmd.Cmd): | 55 | class Commands(cmd.Cmd): |
56 | def __init__(self, initialenv): | 56 | def __init__(self): |
57 | cmd.Cmd.__init__(self) | 57 | cmd.Cmd.__init__(self) |
58 | self.bbhandler = bb.tinfoil.Tinfoil() | ||
58 | self.returncode = 0 | 59 | self.returncode = 0 |
59 | self.config = Config(parse_only=True) | 60 | self.bblayers = (self.bbhandler.config_data.getVar('BBLAYERS', True) or "").split() |
60 | self.cooker = bb.cooker.BBCooker(self.config, | ||
61 | self.register_idle_function, | ||
62 | initialenv) | ||
63 | self.config_data = self.cooker.configuration.data | ||
64 | bb.providers.logger.setLevel(logging.ERROR) | ||
65 | self.cooker_data = None | ||
66 | self.bblayers = (self.config_data.getVar('BBLAYERS', True) or "").split() | ||
67 | |||
68 | def register_idle_function(self, function, data): | ||
69 | pass | ||
70 | |||
71 | def prepare_cooker(self): | ||
72 | sys.stderr.write("Parsing recipes..") | ||
73 | logger.setLevel(logging.WARNING) | ||
74 | |||
75 | try: | ||
76 | while self.cooker.state in (state.initial, state.parsing): | ||
77 | self.cooker.updateCache() | ||
78 | except KeyboardInterrupt: | ||
79 | self.cooker.shutdown() | ||
80 | self.cooker.updateCache() | ||
81 | sys.exit(2) | ||
82 | |||
83 | logger.setLevel(logging.INFO) | ||
84 | sys.stderr.write("done.\n") | ||
85 | |||
86 | self.cooker_data = self.cooker.status | ||
87 | self.cooker_data.appends = self.cooker.appendlist | ||
88 | |||
89 | def check_prepare_cooker(self, config_only = False): | ||
90 | if not self.cooker_data: | ||
91 | if config_only: | ||
92 | self.cooker.parseConfiguration() | ||
93 | self.cooker_data = self.cooker.status | ||
94 | else: | ||
95 | self.prepare_cooker() | ||
96 | 61 | ||
97 | def default(self, line): | 62 | def default(self, line): |
98 | """Handle unrecognised commands""" | 63 | """Handle unrecognised commands""" |
@@ -117,13 +82,13 @@ class Commands(cmd.Cmd): | |||
117 | 82 | ||
118 | def do_show_layers(self, args): | 83 | def do_show_layers(self, args): |
119 | """show current configured layers""" | 84 | """show current configured layers""" |
120 | self.check_prepare_cooker(config_only = True) | 85 | self.bbhandler.prepare(config_only = True) |
121 | logger.plain("%s %s %s" % ("layer".ljust(20), "path".ljust(40), "priority")) | 86 | logger.plain("%s %s %s" % ("layer".ljust(20), "path".ljust(40), "priority")) |
122 | logger.plain('=' * 74) | 87 | logger.plain('=' * 74) |
123 | for layerdir in self.bblayers: | 88 | for layerdir in self.bblayers: |
124 | layername = self.get_layer_name(layerdir) | 89 | layername = self.get_layer_name(layerdir) |
125 | layerpri = 0 | 90 | layerpri = 0 |
126 | for layer, _, regex, pri in self.cooker.status.bbfile_config_priorities: | 91 | for layer, _, regex, pri in self.bbhandler.cooker.status.bbfile_config_priorities: |
127 | if regex.match(os.path.join(layerdir, 'test')): | 92 | if regex.match(os.path.join(layerdir, 'test')): |
128 | layerpri = pri | 93 | layerpri = pri |
129 | break | 94 | break |
@@ -154,7 +119,7 @@ Options: | |||
154 | recipes with the ones they overlay indented underneath | 119 | recipes with the ones they overlay indented underneath |
155 | -s only list overlayed recipes where the version is the same | 120 | -s only list overlayed recipes where the version is the same |
156 | """ | 121 | """ |
157 | self.check_prepare_cooker() | 122 | self.bbhandler.prepare() |
158 | 123 | ||
159 | show_filenames = False | 124 | show_filenames = False |
160 | show_same_ver_only = False | 125 | show_same_ver_only = False |
@@ -186,7 +151,7 @@ Options: | |||
186 | # factor - however, each layer.conf is free to either prepend or append to | 151 | # factor - however, each layer.conf is free to either prepend or append to |
187 | # BBPATH (or indeed do crazy stuff with it). Thus the order in BBPATH might | 152 | # BBPATH (or indeed do crazy stuff with it). Thus the order in BBPATH might |
188 | # not be exactly the order present in bblayers.conf either. | 153 | # not be exactly the order present in bblayers.conf either. |
189 | bbpath = str(self.config_data.getVar('BBPATH', True)) | 154 | bbpath = str(self.bbhandler.config_data.getVar('BBPATH', True)) |
190 | overlayed_class_found = False | 155 | overlayed_class_found = False |
191 | for (classfile, classdirs) in classes.items(): | 156 | for (classfile, classdirs) in classes.items(): |
192 | if len(classdirs) > 1: | 157 | if len(classdirs) > 1: |
@@ -237,7 +202,7 @@ Options: | |||
237 | -m only list where multiple recipes (in the same layer or different | 202 | -m only list where multiple recipes (in the same layer or different |
238 | layers) exist for the same recipe name | 203 | layers) exist for the same recipe name |
239 | """ | 204 | """ |
240 | self.check_prepare_cooker() | 205 | self.bbhandler.prepare() |
241 | 206 | ||
242 | show_filenames = False | 207 | show_filenames = False |
243 | show_multi_provider_only = False | 208 | show_multi_provider_only = False |
@@ -259,15 +224,15 @@ Options: | |||
259 | 224 | ||
260 | 225 | ||
261 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): | 226 | def list_recipes(self, title, pnspec, show_overlayed_only, show_same_ver_only, show_filenames, show_multi_provider_only): |
262 | pkg_pn = self.cooker.status.pkg_pn | 227 | pkg_pn = self.bbhandler.cooker.status.pkg_pn |
263 | (latest_versions, preferred_versions) = bb.providers.findProviders(self.cooker.configuration.data, self.cooker.status, pkg_pn) | 228 | (latest_versions, preferred_versions) = bb.providers.findProviders(self.bbhandler.cooker.configuration.data, self.bbhandler.cooker.status, pkg_pn) |
264 | allproviders = bb.providers.allProviders(self.cooker.status) | 229 | allproviders = bb.providers.allProviders(self.bbhandler.cooker.status) |
265 | 230 | ||
266 | # Ensure we list skipped recipes | 231 | # Ensure we list skipped recipes |
267 | # We are largely guessing about PN, PV and the preferred version here, | 232 | # We are largely guessing about PN, PV and the preferred version here, |
268 | # but we have no choice since skipped recipes are not fully parsed | 233 | # but we have no choice since skipped recipes are not fully parsed |
269 | skiplist = self.cooker.skiplist.keys() | 234 | skiplist = self.bbhandler.cooker.skiplist.keys() |
270 | skiplist.sort( key=lambda fileitem: self.cooker.calc_bbfile_priority(fileitem) ) | 235 | skiplist.sort( key=lambda fileitem: self.bbhandler.cooker.calc_bbfile_priority(fileitem) ) |
271 | skiplist.reverse() | 236 | skiplist.reverse() |
272 | for fn in skiplist: | 237 | for fn in skiplist: |
273 | recipe_parts = os.path.splitext(os.path.basename(fn))[0].split('_') | 238 | recipe_parts = os.path.splitext(os.path.basename(fn))[0].split('_') |
@@ -375,7 +340,7 @@ build results (as the layer priority order has effectively changed). | |||
375 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) | 340 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) |
376 | return | 341 | return |
377 | 342 | ||
378 | self.check_prepare_cooker() | 343 | self.bbhandler.prepare() |
379 | layers = self.bblayers | 344 | layers = self.bblayers |
380 | if len(arglist) > 2: | 345 | if len(arglist) > 2: |
381 | layernames = arglist[:-1] | 346 | layernames = arglist[:-1] |
@@ -405,8 +370,8 @@ build results (as the layer priority order has effectively changed). | |||
405 | appended_recipes = [] | 370 | appended_recipes = [] |
406 | for layer in layers: | 371 | for layer in layers: |
407 | overlayed = [] | 372 | overlayed = [] |
408 | for f in self.cooker.overlayed.iterkeys(): | 373 | for f in self.bbhandler.cooker.overlayed.iterkeys(): |
409 | for of in self.cooker.overlayed[f]: | 374 | for of in self.bbhandler.cooker.overlayed[f]: |
410 | if of.startswith(layer): | 375 | if of.startswith(layer): |
411 | overlayed.append(of) | 376 | overlayed.append(of) |
412 | 377 | ||
@@ -430,8 +395,8 @@ build results (as the layer priority order has effectively changed). | |||
430 | logger.warn('Overwriting file %s', fdest) | 395 | logger.warn('Overwriting file %s', fdest) |
431 | bb.utils.copyfile(f1full, fdest) | 396 | bb.utils.copyfile(f1full, fdest) |
432 | if ext == '.bb': | 397 | if ext == '.bb': |
433 | if f1 in self.cooker_data.appends: | 398 | if f1 in self.bbhandler.cooker.appendlist: |
434 | appends = self.cooker_data.appends[f1] | 399 | appends = self.bbhandler.cooker.appendlist[f1] |
435 | if appends: | 400 | if appends: |
436 | logger.plain(' Applying appends to %s' % fdest ) | 401 | logger.plain(' Applying appends to %s' % fdest ) |
437 | for appendname in appends: | 402 | for appendname in appends: |
@@ -440,9 +405,9 @@ build results (as the layer priority order has effectively changed). | |||
440 | appended_recipes.append(f1) | 405 | appended_recipes.append(f1) |
441 | 406 | ||
442 | # Take care of when some layers are excluded and yet we have included bbappends for those recipes | 407 | # Take care of when some layers are excluded and yet we have included bbappends for those recipes |
443 | for recipename in self.cooker_data.appends.iterkeys(): | 408 | for recipename in self.bbhandler.cooker.appendlist.iterkeys(): |
444 | if recipename not in appended_recipes: | 409 | if recipename not in appended_recipes: |
445 | appends = self.cooker_data.appends[recipename] | 410 | appends = self.bbhandler.cooker.appendlist[recipename] |
446 | first_append = None | 411 | first_append = None |
447 | for appendname in appends: | 412 | for appendname in appends: |
448 | layer = layer_path_match(appendname) | 413 | layer = layer_path_match(appendname) |
@@ -460,14 +425,14 @@ build results (as the layer priority order has effectively changed). | |||
460 | # have come from) | 425 | # have come from) |
461 | first_regex = None | 426 | first_regex = None |
462 | layerdir = layers[0] | 427 | layerdir = layers[0] |
463 | for layername, pattern, regex, _ in self.cooker.status.bbfile_config_priorities: | 428 | for layername, pattern, regex, _ in self.bbhandler.cooker.status.bbfile_config_priorities: |
464 | if regex.match(os.path.join(layerdir, 'test')): | 429 | if regex.match(os.path.join(layerdir, 'test')): |
465 | first_regex = regex | 430 | first_regex = regex |
466 | break | 431 | break |
467 | 432 | ||
468 | if first_regex: | 433 | if first_regex: |
469 | # Find the BBFILES entries that match (which will have come from this conf/layer.conf file) | 434 | # Find the BBFILES entries that match (which will have come from this conf/layer.conf file) |
470 | bbfiles = str(self.config_data.getVar('BBFILES', True)).split() | 435 | bbfiles = str(self.bbhandler.config_data.getVar('BBFILES', True)).split() |
471 | bbfiles_layer = [] | 436 | bbfiles_layer = [] |
472 | for item in bbfiles: | 437 | for item in bbfiles: |
473 | if first_regex.match(item): | 438 | if first_regex.match(item): |
@@ -490,7 +455,7 @@ build results (as the layer priority order has effectively changed). | |||
490 | 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) | 455 | 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) |
491 | 456 | ||
492 | def get_file_layer(self, filename): | 457 | def get_file_layer(self, filename): |
493 | for layer, _, regex, _ in self.cooker.status.bbfile_config_priorities: | 458 | for layer, _, regex, _ in self.bbhandler.cooker.status.bbfile_config_priorities: |
494 | if regex.match(filename): | 459 | if regex.match(filename): |
495 | for layerdir in self.bblayers: | 460 | for layerdir in self.bblayers: |
496 | if regex.match(os.path.join(layerdir, 'test')): | 461 | if regex.match(os.path.join(layerdir, 'test')): |
@@ -516,14 +481,14 @@ usage: show-appends | |||
516 | 481 | ||
517 | Recipes are listed with the bbappends that apply to them as subitems. | 482 | Recipes are listed with the bbappends that apply to them as subitems. |
518 | """ | 483 | """ |
519 | self.check_prepare_cooker() | 484 | self.bbhandler.prepare() |
520 | if not self.cooker_data.appends: | 485 | if not self.bbhandler.cooker.appendlist: |
521 | logger.plain('No append files found') | 486 | logger.plain('No append files found') |
522 | return | 487 | return |
523 | 488 | ||
524 | logger.plain('=== Appended recipes ===') | 489 | logger.plain('=== Appended recipes ===') |
525 | 490 | ||
526 | pnlist = list(self.cooker_data.pkg_pn.keys()) | 491 | pnlist = list(self.bbhandler.cooker_data.pkg_pn.keys()) |
527 | pnlist.sort() | 492 | pnlist.sort() |
528 | for pn in pnlist: | 493 | for pn in pnlist: |
529 | self.show_appends_for_pn(pn) | 494 | self.show_appends_for_pn(pn) |
@@ -531,19 +496,19 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
531 | self.show_appends_for_skipped() | 496 | self.show_appends_for_skipped() |
532 | 497 | ||
533 | def show_appends_for_pn(self, pn): | 498 | def show_appends_for_pn(self, pn): |
534 | filenames = self.cooker_data.pkg_pn[pn] | 499 | filenames = self.bbhandler.cooker_data.pkg_pn[pn] |
535 | 500 | ||
536 | best = bb.providers.findBestProvider(pn, | 501 | best = bb.providers.findBestProvider(pn, |
537 | self.cooker.configuration.data, | 502 | self.bbhandler.cooker.configuration.data, |
538 | self.cooker_data, | 503 | self.bbhandler.cooker_data, |
539 | self.cooker_data.pkg_pn) | 504 | self.bbhandler.cooker_data.pkg_pn) |
540 | best_filename = os.path.basename(best[3]) | 505 | best_filename = os.path.basename(best[3]) |
541 | 506 | ||
542 | self.show_appends_output(filenames, best_filename) | 507 | self.show_appends_output(filenames, best_filename) |
543 | 508 | ||
544 | def show_appends_for_skipped(self): | 509 | def show_appends_for_skipped(self): |
545 | filenames = [os.path.basename(f) | 510 | filenames = [os.path.basename(f) |
546 | for f in self.cooker.skiplist.iterkeys()] | 511 | for f in self.bbhandler.cooker.skiplist.iterkeys()] |
547 | self.show_appends_output(filenames, None, " (skipped)") | 512 | self.show_appends_output(filenames, None, " (skipped)") |
548 | 513 | ||
549 | def show_appends_output(self, filenames, best_filename, name_suffix = ''): | 514 | def show_appends_output(self, filenames, best_filename, name_suffix = ''): |
@@ -569,7 +534,7 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
569 | continue | 534 | continue |
570 | 535 | ||
571 | basename = os.path.basename(filename) | 536 | basename = os.path.basename(filename) |
572 | appends = self.cooker_data.appends.get(basename) | 537 | appends = self.bbhandler.cooker.appendlist.get(basename) |
573 | if appends: | 538 | if appends: |
574 | appended.append((basename, list(appends))) | 539 | appended.append((basename, list(appends))) |
575 | else: | 540 | else: |
@@ -577,22 +542,5 @@ Recipes are listed with the bbappends that apply to them as subitems. | |||
577 | return appended, notappended | 542 | return appended, notappended |
578 | 543 | ||
579 | 544 | ||
580 | class Config(object): | ||
581 | def __init__(self, **options): | ||
582 | self.pkgs_to_build = [] | ||
583 | self.debug_domains = [] | ||
584 | self.extra_assume_provided = [] | ||
585 | self.prefile = [] | ||
586 | self.postfile = [] | ||
587 | self.debug = 0 | ||
588 | self.__dict__.update(options) | ||
589 | |||
590 | def __getattr__(self, attribute): | ||
591 | try: | ||
592 | return super(Config, self).__getattribute__(attribute) | ||
593 | except AttributeError: | ||
594 | return None | ||
595 | |||
596 | |||
597 | if __name__ == '__main__': | 545 | if __name__ == '__main__': |
598 | sys.exit(main(sys.argv[1:]) or 0) | 546 | sys.exit(main(sys.argv[1:]) or 0) |