#!/usr/bin/env python3 # OpenEmbedded Development tool # # Copyright (C) 2014-2015 Intel Corporation # # SPDX-License-Identifier: GPL-2.0-only # import sys import os import argparse import glob import re import configparser import subprocess import logging basepath = '' workspace = {} config = None context = None scripts_path = os.path.dirname(os.path.realpath(__file__)) lib_path = scripts_path + '/lib' sys.path = sys.path + [lib_path] from devtool import DevtoolError, setup_tinfoil import scriptutils import argparse_oe logger = scriptutils.logger_create('devtool') plugins = [] class ConfigHandler(object): config_file = '' config_obj = None init_path = '' workspace_path = '' def __init__(self, filename): self.config_file = filename self.config_obj = configparser.ConfigParser() def get(self, section, option, default=None): try: ret = self.config_obj.get(section, option) except (configparser.NoOptionError, configparser.NoSectionError): if default != None: ret = default else: raise return ret def read(self): if os.path.exists(self.config_file): self.config_obj.read(self.config_file) if self.config_obj.has_option('General', 'init_path'): pth = self.get('General', 'init_path') self.init_path = os.path.join(basepath, pth) if not os.path.exists(self.init_path): logger.error('init_path %s specified in config file cannot be found' % pth) return False else: self.config_obj.add_section('General') self.workspace_path = self.get('General', 'workspace_path', os.path.join(basepath, 'workspace')) return True def write(self): logger.debug('writing to config file %s' % self.config_file) self.config_obj.set('General', 'workspace_path', self.workspace_path) with open(self.config_file, 'w') as f: self.config_obj.write(f) def set(self, section, option, value): if not self.config_obj.has_section(section): self.config_obj.add_section(section) self.config_obj.set(section, option, value) class Context: def __init__(self, **kwargs): self.__dict__.update(kwargs) def read_workspace(): global workspace workspace = {} if not os.path.exists(os.path.join(config.workspace_path, 'conf', 'layer.conf')): if context.fixed_setup: logger.error("workspace layer not set up") sys.exit(1) else: logger.info('Creating workspace layer in %s' % config.workspace_path) _create_workspace(config.workspace_path, config, basepath) if not context.fixed_setup: _enable_workspace_layer(config.workspace_path, config, basepath) logger.debug('Reading workspace in %s' % config.workspace_path) externalsrc_re = re.compile(r'^EXTERNALSRC(_pn-([^ =]+))? *= *"([^"]*)"$') for fn in glob.glob(os.path.join(config.workspace_path, 'appends', '*.bbappend')): with open(fn, 'r') as f: pnvalues = {} for line in f: res = externalsrc_re.match(line.rstrip()) if res: recipepn = os.path.splitext(os.path.basename(fn))[0].split('_')[0] pn = res.group(2) or recipepn # Find the recipe file within the workspace, if any bbfile = os.path.basename(fn).replace('.bbappend', '.bb').replace('%', '*') recipefile = glob.glob(os.path.join(config.workspace_path, 'recipes', recipepn, bbfile)) if recipefile: recipefile = recipefile[0] pnvalues['srctree'] = res.group(3) pnvalues['bbappend'] = fn pnvalues['recipefile'] = recipefile elif line.startswith('# srctreebase: '): pnvalues['srctreebase'] = line.split(':', 1)[1].strip() if pnvalues: if not pnvalues.get('srctreebase', None): pnvalues['srctreebase'] = pnvalues['srctree'] logger.debug('Found recipe %s' % pnvalues) workspace[pn] = pnvalues def create_workspace(args, config, basepath, workspace): if args.layerpath: workspacedir = os.path.abspath(args.layerpath) else: workspacedir = os.path.abspath(os.path.join(basepath, 'workspace')) _create_workspace(workspacedir, config, basepath) if not args.create_only: _enable_workspace_layer(workspacedir, config, basepath) def _create_workspace(workspacedir, config, basepath): import bb confdir = os.path.join(workspacedir, 'conf') if os.path.exists(os.path.join(confdir, 'layer.conf')): logger.info('Specified workspace already set up, leaving as-is') else: # Add a config file bb.utils.mkdirhier(confdir) with open(os.path.join(confdir, 'layer.conf'), 'w') as f: f.write('# ### workspace layer auto-generated by devtool ###\n') f.write('BBPATH =. "$' + '{LAYERDIR}:"\n') f.write('BBFILES += "$' + '{LAYERDIR}/recipes/*/*.bb \\\n') f.write(' $' + '{LAYERDIR}/appends/*.bbappend"\n') f.write('BBFILE_COLLECTIONS += "workspacelayer"\n') f.write('BBFILE_PATTERN_workspacelayer = "^$' + '{LAYERDIR}/"\n') f.write('BBFILE_PATTERN_IGNORE_EMPTY_workspacelayer = "1"\n') f.write('BBFILE_PRIORITY_workspacelayer = "99"\n') f.write('LAYERSERIES_COMPAT_workspacelayer = "${LAYERSERIES_COMPAT_core}"\n') # Add a README file with open(os.path.join(workspacedir, 'README'), 'w') as f: f.write('This layer was created by the OpenEmbedded devtool utility in order to\n') f.write('contain recipes and bbappends that are currently being worked on. The idea\n') f.write('is that the contents is temporary - once you have finished working on a\n') f.write('recipe you use the appropriate method to move the files you have been\n