2011-03-03 14:15:47 +00:00
|
|
|
#!/usr/bin/env python
|
2011-02-07 17:50:27 +00:00
|
|
|
|
2011-03-02 17:59:38 +00:00
|
|
|
# This script has subcommands which operate against your bitbake layers, either
|
|
|
|
# displaying useful information, or acting against them.
|
|
|
|
# Currently, it only provides a show_appends command, which shows you what
|
|
|
|
# bbappends are in effect, and warns you if you have appends which are not being
|
|
|
|
# utilized.
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
import cmd
|
|
|
|
import logging
|
|
|
|
import os.path
|
|
|
|
import sys
|
|
|
|
|
|
|
|
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
|
2011-06-29 18:37:40 +00:00
|
|
|
import bb.utils
|
2011-02-07 17:50:27 +00:00
|
|
|
from bb.cooker import state
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger('BitBake')
|
|
|
|
default_cmd = 'show_appends'
|
|
|
|
|
|
|
|
|
|
|
|
def main(args):
|
|
|
|
logging.basicConfig(format='%(levelname)s: %(message)s')
|
2011-02-07 17:58:40 +00:00
|
|
|
bb.utils.clean_environment()
|
2011-02-07 17:50:27 +00:00
|
|
|
|
|
|
|
cmds = Commands()
|
|
|
|
if args:
|
|
|
|
cmds.onecmd(' '.join(args))
|
|
|
|
else:
|
|
|
|
cmds.onecmd(default_cmd)
|
|
|
|
return cmds.returncode
|
|
|
|
|
|
|
|
|
|
|
|
class Commands(cmd.Cmd):
|
|
|
|
def __init__(self):
|
|
|
|
cmd.Cmd.__init__(self)
|
|
|
|
|
|
|
|
self.returncode = 0
|
|
|
|
self.config = Config(parse_only=True)
|
|
|
|
self.cooker = bb.cooker.BBCooker(self.config,
|
2011-06-08 16:25:41 +00:00
|
|
|
self.register_idle_function)
|
2011-02-07 17:50:27 +00:00
|
|
|
self.config_data = self.cooker.configuration.data
|
|
|
|
bb.providers.logger.setLevel(logging.ERROR)
|
2011-07-22 16:03:55 +00:00
|
|
|
self.cooker_data = None
|
2011-02-07 17:50:27 +00:00
|
|
|
|
2011-06-08 16:25:41 +00:00
|
|
|
def register_idle_function(self, function, data):
|
|
|
|
pass
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
def prepare_cooker(self):
|
|
|
|
sys.stderr.write("Parsing recipes..")
|
2011-07-02 15:15:30 +00:00
|
|
|
logger.setLevel(logging.WARNING)
|
2011-02-07 17:50:27 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
while self.cooker.state in (state.initial, state.parsing):
|
|
|
|
self.cooker.updateCache()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
self.cooker.shutdown()
|
|
|
|
self.cooker.updateCache()
|
|
|
|
sys.exit(2)
|
|
|
|
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
sys.stderr.write("done.\n")
|
|
|
|
|
|
|
|
self.cooker_data = self.cooker.status
|
|
|
|
self.cooker_data.appends = self.cooker.appendlist
|
|
|
|
|
2011-07-22 16:03:55 +00:00
|
|
|
def check_prepare_cooker(self):
|
|
|
|
if not self.cooker_data:
|
|
|
|
self.prepare_cooker()
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
def do_show_layers(self, args):
|
2011-07-22 16:03:55 +00:00
|
|
|
self.check_prepare_cooker()
|
2011-02-07 17:50:27 +00:00
|
|
|
logger.info(str(self.config_data.getVar('BBLAYERS', True)))
|
|
|
|
|
2011-06-29 18:37:38 +00:00
|
|
|
def do_show_overlayed(self, args):
|
2011-07-22 16:03:55 +00:00
|
|
|
self.check_prepare_cooker()
|
2011-06-29 18:37:38 +00:00
|
|
|
if self.cooker.overlayed:
|
|
|
|
logger.info('Overlayed recipes:')
|
|
|
|
for f in self.cooker.overlayed.iterkeys():
|
|
|
|
logger.info('%s' % f)
|
|
|
|
for of in self.cooker.overlayed[f]:
|
|
|
|
logger.info(' %s' % of)
|
|
|
|
else:
|
|
|
|
logger.info('No overlayed recipes found')
|
|
|
|
|
2011-06-29 18:37:40 +00:00
|
|
|
def do_flatten(self, args):
|
|
|
|
arglist = args.split()
|
|
|
|
if len(arglist) != 1:
|
|
|
|
logger.error('syntax: flatten <outputdir>')
|
|
|
|
return
|
|
|
|
|
|
|
|
if os.path.exists(arglist[0]) and os.listdir(arglist[0]):
|
|
|
|
logger.error('Directory %s exists and is non-empty, please clear it out first' % arglist[0])
|
|
|
|
return
|
|
|
|
|
2011-07-22 16:03:55 +00:00
|
|
|
self.check_prepare_cooker()
|
2011-06-29 18:37:40 +00:00
|
|
|
layers = (self.config_data.getVar('BBLAYERS', True) or "").split()
|
|
|
|
for layer in layers:
|
|
|
|
overlayed = []
|
|
|
|
for f in self.cooker.overlayed.iterkeys():
|
|
|
|
for of in self.cooker.overlayed[f]:
|
|
|
|
if of.startswith(layer):
|
|
|
|
overlayed.append(of)
|
|
|
|
|
|
|
|
logger.info('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.info(' 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([arglist[0],fdest]))
|
|
|
|
bb.utils.mkdirhier(os.path.dirname(fdest))
|
|
|
|
if os.path.exists(fdest):
|
|
|
|
if f1 == 'layer.conf' and root.endswith('/conf'):
|
|
|
|
logger.info(' 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.cooker_data.appends:
|
|
|
|
appends = self.cooker_data.appends[f1]
|
|
|
|
if appends:
|
|
|
|
logger.info(' Applying appends to %s' % fdest )
|
|
|
|
for appendname in appends:
|
|
|
|
self.apply_append(appendname, fdest)
|
|
|
|
|
|
|
|
def get_append_layer(self, appendname):
|
|
|
|
for layer, _, regex, _ in self.cooker.status.bbfile_config_priorities:
|
|
|
|
if regex.match(appendname):
|
|
|
|
return layer
|
|
|
|
return "?"
|
|
|
|
|
|
|
|
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_append_layer(appendname))
|
|
|
|
recipefile.writelines(appendfile.readlines())
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
def do_show_appends(self, args):
|
2011-07-22 16:03:55 +00:00
|
|
|
self.check_prepare_cooker()
|
2011-02-07 17:50:27 +00:00
|
|
|
if not self.cooker_data.appends:
|
|
|
|
logger.info('No append files found')
|
|
|
|
return
|
|
|
|
|
|
|
|
logger.info('State of append files:')
|
|
|
|
|
2011-06-29 18:37:41 +00:00
|
|
|
pnlist = list(self.cooker_data.pkg_pn.keys())
|
2011-07-05 13:25:05 +00:00
|
|
|
pnlist.sort()
|
2011-06-29 18:37:41 +00:00
|
|
|
for pn in pnlist:
|
2011-02-07 17:50:27 +00:00
|
|
|
self.show_appends_for_pn(pn)
|
|
|
|
|
2011-06-01 16:48:32 +00:00
|
|
|
self.show_appends_for_skipped()
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
def show_appends_for_pn(self, pn):
|
|
|
|
filenames = self.cooker_data.pkg_pn[pn]
|
|
|
|
|
|
|
|
best = bb.providers.findBestProvider(pn,
|
|
|
|
self.cooker.configuration.data,
|
|
|
|
self.cooker_data,
|
|
|
|
self.cooker_data.pkg_pn)
|
|
|
|
best_filename = os.path.basename(best[3])
|
|
|
|
|
2011-06-01 16:48:32 +00:00
|
|
|
self.show_appends_output(filenames, best_filename)
|
|
|
|
|
|
|
|
def show_appends_for_skipped(self):
|
|
|
|
filenames = [os.path.basename(f)
|
|
|
|
for f in self.cooker.skiplist.iterkeys()]
|
|
|
|
self.show_appends_output(filenames, None, " (skipped)")
|
|
|
|
|
|
|
|
def show_appends_output(self, filenames, best_filename, name_suffix = ''):
|
2011-02-07 17:50:27 +00:00
|
|
|
appended, missing = self.get_appends_for_files(filenames)
|
|
|
|
if appended:
|
|
|
|
for basename, appends in appended:
|
2011-06-01 16:48:32 +00:00
|
|
|
logger.info('%s%s:', basename, name_suffix)
|
2011-02-07 17:50:27 +00:00
|
|
|
for append in appends:
|
|
|
|
logger.info(' %s', append)
|
|
|
|
|
2011-06-01 16:48:32 +00:00
|
|
|
if best_filename:
|
|
|
|
if best_filename in missing:
|
|
|
|
logger.warn('%s: missing append for preferred version',
|
|
|
|
best_filename)
|
|
|
|
self.returncode |= 1
|
|
|
|
|
2011-02-07 17:50:27 +00:00
|
|
|
|
|
|
|
def get_appends_for_files(self, filenames):
|
2011-06-29 18:37:41 +00:00
|
|
|
appended, notappended = [], []
|
2011-02-07 17:50:27 +00:00
|
|
|
for filename in filenames:
|
|
|
|
_, cls = bb.cache.Cache.virtualfn2realfn(filename)
|
|
|
|
if cls:
|
|
|
|
continue
|
|
|
|
|
|
|
|
basename = os.path.basename(filename)
|
|
|
|
appends = self.cooker_data.appends.get(basename)
|
|
|
|
if appends:
|
2011-06-29 18:37:41 +00:00
|
|
|
appended.append((basename, list(appends)))
|
2011-02-07 17:50:27 +00:00
|
|
|
else:
|
2011-06-29 18:37:41 +00:00
|
|
|
notappended.append(basename)
|
2011-02-07 17:50:27 +00:00
|
|
|
return appended, notappended
|
|
|
|
|
|
|
|
def do_EOF(self, line):
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
class Config(object):
|
|
|
|
def __init__(self, **options):
|
|
|
|
self.pkgs_to_build = []
|
|
|
|
self.debug_domains = []
|
|
|
|
self.extra_assume_provided = []
|
2011-07-05 13:25:06 +00:00
|
|
|
self.prefile = []
|
|
|
|
self.postfile = []
|
2011-02-07 17:50:27 +00:00
|
|
|
self.debug = 0
|
|
|
|
self.__dict__.update(options)
|
|
|
|
|
|
|
|
def __getattr__(self, attribute):
|
|
|
|
try:
|
|
|
|
return super(Config, self).__getattribute__(attribute)
|
|
|
|
except AttributeError:
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
sys.exit(main(sys.argv[1:]) or 0)
|