summaryrefslogtreecommitdiffstats
path: root/bitbake/bin
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2012-08-27 21:44:31 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-09-07 12:10:43 +0100
commit56a66a1fabc945cd3673786dd0e7b17eaddcd7dc (patch)
tree91a84a75ae43a5c5624c3d2d8100b229f44811ab /bitbake/bin
parente8d87846e3d9ce568cc0280bad84174e151a6610 (diff)
downloadpoky-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')
-rwxr-xr-xbitbake/bin/bitbake-layers146
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
10import cmd 23import cmd
11import logging 24import logging
12import warnings
13import os 25import os
14import sys 26import sys
15import fnmatch 27import fnmatch
@@ -23,26 +35,14 @@ import bb.cache
23import bb.cooker 35import bb.cooker
24import bb.providers 36import bb.providers
25import bb.utils 37import bb.utils
26from bb.cooker import state 38import bb.tinfoil
27import bb.fetch2
28 39
29 40
30logger = logging.getLogger('BitBake') 41logger = logging.getLogger('BitBake')
31 42
32warnings.filterwarnings("ignore", category=DeprecationWarning)
33 43
34def main(args): 44def 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
55class Commands(cmd.Cmd): 55class 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
517Recipes are listed with the bbappends that apply to them as subitems. 482Recipes 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
580class 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
597if __name__ == '__main__': 545if __name__ == '__main__':
598 sys.exit(main(sys.argv[1:]) or 0) 546 sys.exit(main(sys.argv[1:]) or 0)