| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # | 
|  | 2 | # Copyright (C) 2003, 2004  Chris Larson | 
|  | 3 | # Copyright (C) 2003, 2004  Phil Blundell | 
|  | 4 | # Copyright (C) 2003 - 2005 Michael 'Mickey' Lauer | 
|  | 5 | # Copyright (C) 2005        Holger Hans Peter Freyther | 
|  | 6 | # Copyright (C) 2005        ROAD GmbH | 
|  | 7 | # Copyright (C) 2006        Richard Purdie | 
|  | 8 | # | 
| Brad Bishop | c342db3 | 2019-05-15 21:57:59 -0400 | [diff] [blame] | 9 | # SPDX-License-Identifier: GPL-2.0-only | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 10 | # | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 11 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 12 | import logging | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 13 | import os | 
|  | 14 | import re | 
|  | 15 | import sys | 
| Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 16 | import hashlib | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 17 | from functools import wraps | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 18 | import bb | 
|  | 19 | from bb import data | 
|  | 20 | import bb.parse | 
|  | 21 |  | 
|  | 22 | logger      = logging.getLogger("BitBake") | 
|  | 23 | parselog    = logging.getLogger("BitBake.Parsing") | 
|  | 24 |  | 
|  | 25 | class ConfigParameters(object): | 
|  | 26 | def __init__(self, argv=sys.argv): | 
|  | 27 | self.options, targets = self.parseCommandLine(argv) | 
|  | 28 | self.environment = self.parseEnvironment() | 
|  | 29 |  | 
|  | 30 | self.options.pkgs_to_build = targets or [] | 
|  | 31 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 32 | for key, val in self.options.__dict__.items(): | 
|  | 33 | setattr(self, key, val) | 
|  | 34 |  | 
|  | 35 | def parseCommandLine(self, argv=sys.argv): | 
|  | 36 | raise Exception("Caller must implement commandline option parsing") | 
|  | 37 |  | 
|  | 38 | def parseEnvironment(self): | 
|  | 39 | return os.environ.copy() | 
|  | 40 |  | 
|  | 41 | def updateFromServer(self, server): | 
|  | 42 | if not self.options.cmd: | 
|  | 43 | defaulttask, error = server.runCommand(["getVariable", "BB_DEFAULT_TASK"]) | 
|  | 44 | if error: | 
|  | 45 | raise Exception("Unable to get the value of BB_DEFAULT_TASK from the server: %s" % error) | 
|  | 46 | self.options.cmd = defaulttask or "build" | 
|  | 47 | _, error = server.runCommand(["setConfig", "cmd", self.options.cmd]) | 
|  | 48 | if error: | 
|  | 49 | raise Exception("Unable to set configuration option 'cmd' on the server: %s" % error) | 
|  | 50 |  | 
|  | 51 | if not self.options.pkgs_to_build: | 
| Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 52 | bbpkgs, error = server.runCommand(["getVariable", "BBTARGETS"]) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 53 | if error: | 
| Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 54 | raise Exception("Unable to get the value of BBTARGETS from the server: %s" % error) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 55 | if bbpkgs: | 
|  | 56 | self.options.pkgs_to_build.extend(bbpkgs.split()) | 
|  | 57 |  | 
|  | 58 | def updateToServer(self, server, environment): | 
|  | 59 | options = {} | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 60 | for o in ["abort", "force", "invalidate_stamp", | 
|  | 61 | "verbose", "debug", "dry_run", "dump_signatures", | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 62 | "debug_domains", "extra_assume_provided", "profile", | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 63 | "prefile", "postfile", "server_timeout"]: | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 64 | options[o] = getattr(self.options, o) | 
|  | 65 |  | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 66 | ret, error = server.runCommand(["updateConfig", options, environment, sys.argv]) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 67 | if error: | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 68 | raise Exception("Unable to update the server configuration with local parameters: %s" % error) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 69 |  | 
|  | 70 | def parseActions(self): | 
|  | 71 | # Parse any commandline into actions | 
|  | 72 | action = {'action':None, 'msg':None} | 
|  | 73 | if self.options.show_environment: | 
|  | 74 | if 'world' in self.options.pkgs_to_build: | 
|  | 75 | action['msg'] = "'world' is not a valid target for --environment." | 
|  | 76 | elif 'universe' in self.options.pkgs_to_build: | 
|  | 77 | action['msg'] = "'universe' is not a valid target for --environment." | 
|  | 78 | elif len(self.options.pkgs_to_build) > 1: | 
|  | 79 | action['msg'] = "Only one target can be used with the --environment option." | 
|  | 80 | elif self.options.buildfile and len(self.options.pkgs_to_build) > 0: | 
|  | 81 | action['msg'] = "No target should be used with the --environment and --buildfile options." | 
|  | 82 | elif len(self.options.pkgs_to_build) > 0: | 
|  | 83 | action['action'] = ["showEnvironmentTarget", self.options.pkgs_to_build] | 
|  | 84 | else: | 
|  | 85 | action['action'] = ["showEnvironment", self.options.buildfile] | 
|  | 86 | elif self.options.buildfile is not None: | 
|  | 87 | action['action'] = ["buildFile", self.options.buildfile, self.options.cmd] | 
|  | 88 | elif self.options.revisions_changed: | 
|  | 89 | action['action'] = ["compareRevisions"] | 
|  | 90 | elif self.options.show_versions: | 
|  | 91 | action['action'] = ["showVersions"] | 
|  | 92 | elif self.options.parse_only: | 
|  | 93 | action['action'] = ["parseFiles"] | 
|  | 94 | elif self.options.dot_graph: | 
|  | 95 | if self.options.pkgs_to_build: | 
|  | 96 | action['action'] = ["generateDotGraph", self.options.pkgs_to_build, self.options.cmd] | 
|  | 97 | else: | 
|  | 98 | action['msg'] = "Please specify a package name for dependency graph generation." | 
|  | 99 | else: | 
|  | 100 | if self.options.pkgs_to_build: | 
|  | 101 | action['action'] = ["buildTargets", self.options.pkgs_to_build, self.options.cmd] | 
|  | 102 | else: | 
|  | 103 | #action['msg'] = "Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information." | 
|  | 104 | action = None | 
|  | 105 | self.options.initialaction = action | 
|  | 106 | return action | 
|  | 107 |  | 
|  | 108 | class CookerConfiguration(object): | 
|  | 109 | """ | 
|  | 110 | Manages build options and configurations for one run | 
|  | 111 | """ | 
|  | 112 |  | 
|  | 113 | def __init__(self): | 
|  | 114 | self.debug_domains = [] | 
|  | 115 | self.extra_assume_provided = [] | 
|  | 116 | self.prefile = [] | 
|  | 117 | self.postfile = [] | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 118 | self.debug = 0 | 
|  | 119 | self.cmd = None | 
|  | 120 | self.abort = True | 
|  | 121 | self.force = False | 
|  | 122 | self.profile = False | 
|  | 123 | self.nosetscene = False | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 124 | self.setsceneonly = False | 
| Brad Bishop | 96ff198 | 2019-08-19 13:50:42 -0400 | [diff] [blame] | 125 | self.skipsetscene = False | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 126 | self.invalidate_stamp = False | 
|  | 127 | self.dump_signatures = [] | 
|  | 128 | self.dry_run = False | 
|  | 129 | self.tracking = False | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 130 | self.xmlrpcinterface = [] | 
|  | 131 | self.server_timeout = None | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 132 | self.writeeventlog = False | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 133 | self.server_only = False | 
|  | 134 | self.limited_deps = False | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 135 | self.runall = [] | 
|  | 136 | self.runonly = [] | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 137 |  | 
|  | 138 | self.env = {} | 
|  | 139 |  | 
|  | 140 | def setConfigParameters(self, parameters): | 
|  | 141 | for key in self.__dict__.keys(): | 
|  | 142 | if key in parameters.options.__dict__: | 
|  | 143 | setattr(self, key, parameters.options.__dict__[key]) | 
|  | 144 | self.env = parameters.environment.copy() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 145 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 146 | def __getstate__(self): | 
|  | 147 | state = {} | 
|  | 148 | for key in self.__dict__.keys(): | 
| Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 149 | state[key] = getattr(self, key) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 150 | return state | 
|  | 151 |  | 
|  | 152 | def __setstate__(self,state): | 
|  | 153 | for k in state: | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 154 | setattr(self, k, state[k]) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 155 |  | 
|  | 156 |  | 
|  | 157 | def catch_parse_error(func): | 
|  | 158 | """Exception handling bits for our parsing""" | 
|  | 159 | @wraps(func) | 
|  | 160 | def wrapped(fn, *args): | 
|  | 161 | try: | 
|  | 162 | return func(fn, *args) | 
|  | 163 | except IOError as exc: | 
|  | 164 | import traceback | 
|  | 165 | parselog.critical(traceback.format_exc()) | 
|  | 166 | parselog.critical("Unable to parse %s: %s" % (fn, exc)) | 
|  | 167 | sys.exit(1) | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 168 | except bb.data_smart.ExpansionError as exc: | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 169 | import traceback | 
|  | 170 |  | 
|  | 171 | bbdir = os.path.dirname(__file__) + os.sep | 
|  | 172 | exc_class, exc, tb = sys.exc_info() | 
|  | 173 | for tb in iter(lambda: tb.tb_next, None): | 
|  | 174 | # Skip frames in bitbake itself, we only want the metadata | 
|  | 175 | fn, _, _, _ = traceback.extract_tb(tb, 1)[0] | 
|  | 176 | if not fn.startswith(bbdir): | 
|  | 177 | break | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 178 | parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb)) | 
|  | 179 | sys.exit(1) | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 180 | except bb.parse.ParseError as exc: | 
|  | 181 | parselog.critical(str(exc)) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 182 | sys.exit(1) | 
|  | 183 | return wrapped | 
|  | 184 |  | 
|  | 185 | @catch_parse_error | 
|  | 186 | def parse_config_file(fn, data, include=True): | 
|  | 187 | return bb.parse.handle(fn, data, include) | 
|  | 188 |  | 
|  | 189 | @catch_parse_error | 
|  | 190 | def _inherit(bbclass, data): | 
|  | 191 | bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data) | 
|  | 192 | return data | 
|  | 193 |  | 
|  | 194 | def findConfigFile(configfile, data): | 
|  | 195 | search = [] | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 196 | bbpath = data.getVar("BBPATH") | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 197 | if bbpath: | 
|  | 198 | for i in bbpath.split(":"): | 
|  | 199 | search.append(os.path.join(i, "conf", configfile)) | 
|  | 200 | path = os.getcwd() | 
|  | 201 | while path != "/": | 
|  | 202 | search.append(os.path.join(path, "conf", configfile)) | 
|  | 203 | path, _ = os.path.split(path) | 
|  | 204 |  | 
|  | 205 | for i in search: | 
|  | 206 | if os.path.exists(i): | 
|  | 207 | return i | 
|  | 208 |  | 
|  | 209 | return None | 
|  | 210 |  | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 211 | # | 
|  | 212 | # We search for a conf/bblayers.conf under an entry in BBPATH or in cwd working | 
|  | 213 | # up to /. If that fails, we search for a conf/bitbake.conf in BBPATH. | 
|  | 214 | # | 
|  | 215 |  | 
|  | 216 | def findTopdir(): | 
|  | 217 | d = bb.data.init() | 
|  | 218 | bbpath = None | 
|  | 219 | if 'BBPATH' in os.environ: | 
|  | 220 | bbpath = os.environ['BBPATH'] | 
|  | 221 | d.setVar('BBPATH', bbpath) | 
|  | 222 |  | 
|  | 223 | layerconf = findConfigFile("bblayers.conf", d) | 
|  | 224 | if layerconf: | 
|  | 225 | return os.path.dirname(os.path.dirname(layerconf)) | 
|  | 226 | if bbpath: | 
|  | 227 | bitbakeconf = bb.utils.which(bbpath, "conf/bitbake.conf") | 
|  | 228 | if bitbakeconf: | 
|  | 229 | return os.path.dirname(os.path.dirname(bitbakeconf)) | 
|  | 230 | return None | 
|  | 231 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 232 | class CookerDataBuilder(object): | 
|  | 233 |  | 
|  | 234 | def __init__(self, cookercfg, worker = False): | 
|  | 235 |  | 
|  | 236 | self.prefiles = cookercfg.prefile | 
|  | 237 | self.postfiles = cookercfg.postfile | 
|  | 238 | self.tracking = cookercfg.tracking | 
|  | 239 |  | 
|  | 240 | bb.utils.set_context(bb.utils.clean_context()) | 
|  | 241 | bb.event.set_class_handlers(bb.event.clean_class_handlers()) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 242 | self.basedata = bb.data.init() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 243 | if self.tracking: | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 244 | self.basedata.enableTracking() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 245 |  | 
|  | 246 | # Keep a datastore of the initial environment variables and their | 
|  | 247 | # values from when BitBake was launched to enable child processes | 
|  | 248 | # to use environment variables which have been cleaned from the | 
|  | 249 | # BitBake processes env | 
|  | 250 | self.savedenv = bb.data.init() | 
|  | 251 | for k in cookercfg.env: | 
|  | 252 | self.savedenv.setVar(k, cookercfg.env[k]) | 
|  | 253 |  | 
|  | 254 | filtered_keys = bb.utils.approved_variables() | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 255 | bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys) | 
|  | 256 | self.basedata.setVar("BB_ORIGENV", self.savedenv) | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 257 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 258 | if worker: | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 259 | self.basedata.setVar("BB_WORKERCONTEXT", "1") | 
|  | 260 |  | 
|  | 261 | self.data = self.basedata | 
|  | 262 | self.mcdata = {} | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 263 |  | 
|  | 264 | def parseBaseConfiguration(self): | 
| Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 265 | data_hash = hashlib.sha256() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 266 | try: | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 267 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) | 
|  | 268 |  | 
|  | 269 | if self.data.getVar("BB_WORKERCONTEXT", False) is None: | 
|  | 270 | bb.fetch.fetcher_init(self.data) | 
| Brad Bishop | c68388fc | 2019-08-26 01:33:31 -0400 | [diff] [blame] | 271 | bb.parse.init_parser(self.data) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 272 | bb.codeparser.parser_cache_init(self.data) | 
|  | 273 |  | 
|  | 274 | bb.event.fire(bb.event.ConfigParsed(), self.data) | 
|  | 275 |  | 
|  | 276 | reparse_cnt = 0 | 
|  | 277 | while self.data.getVar("BB_INVALIDCONF", False) is True: | 
|  | 278 | if reparse_cnt > 20: | 
|  | 279 | logger.error("Configuration has been re-parsed over 20 times, " | 
|  | 280 | "breaking out of the loop...") | 
|  | 281 | raise Exception("Too deep config re-parse loop. Check locations where " | 
|  | 282 | "BB_INVALIDCONF is being set (ConfigParsed event handlers)") | 
|  | 283 | self.data.setVar("BB_INVALIDCONF", False) | 
|  | 284 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) | 
|  | 285 | reparse_cnt += 1 | 
|  | 286 | bb.event.fire(bb.event.ConfigParsed(), self.data) | 
|  | 287 |  | 
|  | 288 | bb.parse.init_parser(self.data) | 
| Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 289 | data_hash.update(self.data.get_hash().encode('utf-8')) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 290 | self.mcdata[''] = self.data | 
|  | 291 |  | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 292 | multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split() | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 293 | for config in multiconfig: | 
| Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 294 | mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 295 | bb.event.fire(bb.event.ConfigParsed(), mcdata) | 
|  | 296 | self.mcdata[config] = mcdata | 
| Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 297 | data_hash.update(mcdata.get_hash().encode('utf-8')) | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 298 | if multiconfig: | 
|  | 299 | bb.event.fire(bb.event.MultiConfigParsed(self.mcdata), self.data) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 300 |  | 
| Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 301 | self.data_hash = data_hash.hexdigest() | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 302 | except (SyntaxError, bb.BBHandledException): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 303 | raise bb.BBHandledException | 
|  | 304 | except bb.data_smart.ExpansionError as e: | 
|  | 305 | logger.error(str(e)) | 
|  | 306 | raise bb.BBHandledException | 
|  | 307 | except Exception: | 
|  | 308 | logger.exception("Error parsing configuration files") | 
|  | 309 | raise bb.BBHandledException | 
|  | 310 |  | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 311 | # Create a copy so we can reset at a later date when UIs disconnect | 
|  | 312 | self.origdata = self.data | 
|  | 313 | self.data = bb.data.createCopy(self.origdata) | 
|  | 314 | self.mcdata[''] = self.data | 
|  | 315 |  | 
|  | 316 | def reset(self): | 
|  | 317 | # We may not have run parseBaseConfiguration() yet | 
|  | 318 | if not hasattr(self, 'origdata'): | 
|  | 319 | return | 
|  | 320 | self.data = bb.data.createCopy(self.origdata) | 
|  | 321 | self.mcdata[''] = self.data | 
|  | 322 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 323 | def _findLayerConf(self, data): | 
|  | 324 | return findConfigFile("bblayers.conf", data) | 
|  | 325 |  | 
| Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 326 | def parseConfigurationFiles(self, prefiles, postfiles, mc = "default"): | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 327 | data = bb.data.createCopy(self.basedata) | 
| Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 328 | data.setVar("BB_CURRENT_MC", mc) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 329 |  | 
|  | 330 | # Parse files for loading *before* bitbake.conf and any includes | 
|  | 331 | for f in prefiles: | 
|  | 332 | data = parse_config_file(f, data) | 
|  | 333 |  | 
|  | 334 | layerconf = self._findLayerConf(data) | 
|  | 335 | if layerconf: | 
|  | 336 | parselog.debug(2, "Found bblayers.conf (%s)", layerconf) | 
|  | 337 | # By definition bblayers.conf is in conf/ of TOPDIR. | 
|  | 338 | # We may have been called with cwd somewhere else so reset TOPDIR | 
|  | 339 | data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf))) | 
|  | 340 | data = parse_config_file(layerconf, data) | 
|  | 341 |  | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 342 | layers = (data.getVar('BBLAYERS') or "").split() | 
| Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 343 | broken_layers = [] | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 344 |  | 
|  | 345 | data = bb.data.createCopy(data) | 
|  | 346 | approved = bb.utils.approved_variables() | 
| Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 347 |  | 
|  | 348 | # Check whether present layer directories exist | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 349 | for layer in layers: | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 350 | if not os.path.isdir(layer): | 
| Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 351 | broken_layers.append(layer) | 
|  | 352 |  | 
|  | 353 | if broken_layers: | 
|  | 354 | parselog.critical("The following layer directories do not exist:") | 
|  | 355 | for layer in broken_layers: | 
|  | 356 | parselog.critical("   %s", layer) | 
|  | 357 | parselog.critical("Please check BBLAYERS in %s" % (layerconf)) | 
|  | 358 | sys.exit(1) | 
|  | 359 |  | 
|  | 360 | for layer in layers: | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 361 | parselog.debug(2, "Adding layer %s", layer) | 
|  | 362 | if 'HOME' in approved and '~' in layer: | 
|  | 363 | layer = os.path.expanduser(layer) | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 364 | if layer.endswith('/'): | 
|  | 365 | layer = layer.rstrip('/') | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 366 | data.setVar('LAYERDIR', layer) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 367 | data.setVar('LAYERDIR_RE', re.escape(layer)) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 368 | data = parse_config_file(os.path.join(layer, "conf", "layer.conf"), data) | 
|  | 369 | data.expandVarref('LAYERDIR') | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 370 | data.expandVarref('LAYERDIR_RE') | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 371 |  | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 372 | data.delVar('LAYERDIR_RE') | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 373 | data.delVar('LAYERDIR') | 
|  | 374 |  | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 375 | bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split() | 
|  | 376 | collections = (data.getVar('BBFILE_COLLECTIONS') or "").split() | 
|  | 377 | invalid = [] | 
|  | 378 | for entry in bbfiles_dynamic: | 
|  | 379 | parts = entry.split(":", 1) | 
|  | 380 | if len(parts) != 2: | 
|  | 381 | invalid.append(entry) | 
|  | 382 | continue | 
|  | 383 | l, f = parts | 
| Andrew Geissler | d25ed32 | 2020-06-27 00:28:28 -0500 | [diff] [blame] | 384 | invert = l[0] == "!" | 
|  | 385 | if invert: | 
|  | 386 | l = l[1:] | 
|  | 387 | if (l in collections and not invert) or (l not in collections and invert): | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 388 | data.appendVar("BBFILES", " " + f) | 
|  | 389 | if invalid: | 
| Andrew Geissler | d25ed32 | 2020-06-27 00:28:28 -0500 | [diff] [blame] | 390 | bb.fatal("BBFILES_DYNAMIC entries must be of the form {!}<collection name>:<filename pattern>, not:\n    %s" % "\n    ".join(invalid)) | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 391 |  | 
|  | 392 | layerseries = set((data.getVar("LAYERSERIES_CORENAMES") or "").split()) | 
| Brad Bishop | 1932369 | 2019-04-05 15:28:33 -0400 | [diff] [blame] | 393 | collections_tmp = collections[:] | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 394 | for c in collections: | 
| Brad Bishop | 1932369 | 2019-04-05 15:28:33 -0400 | [diff] [blame] | 395 | collections_tmp.remove(c) | 
|  | 396 | if c in collections_tmp: | 
|  | 397 | bb.fatal("Found duplicated BBFILE_COLLECTIONS '%s', check bblayers.conf or layer.conf to fix it." % c) | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 398 | compat = set((data.getVar("LAYERSERIES_COMPAT_%s" % c) or "").split()) | 
|  | 399 | if compat and not (compat & layerseries): | 
|  | 400 | bb.fatal("Layer %s is not compatible with the core layer which only supports these series: %s (layer is compatible with %s)" | 
|  | 401 | % (c, " ".join(layerseries), " ".join(compat))) | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 402 | elif not compat and not data.getVar("BB_WORKERCONTEXT"): | 
|  | 403 | bb.warn("Layer %s should set LAYERSERIES_COMPAT_%s in its conf/layer.conf file to list the core layer names it is compatible with." % (c, c)) | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 404 |  | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 405 | if not data.getVar("BBPATH"): | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 406 | msg = "The BBPATH variable is not set" | 
|  | 407 | if not layerconf: | 
|  | 408 | msg += (" and bitbake did not find a conf/bblayers.conf file in" | 
|  | 409 | " the expected location.\nMaybe you accidentally" | 
|  | 410 | " invoked bitbake from the wrong directory?") | 
|  | 411 | raise SystemExit(msg) | 
|  | 412 |  | 
|  | 413 | data = parse_config_file(os.path.join("conf", "bitbake.conf"), data) | 
|  | 414 |  | 
|  | 415 | # Parse files for loading *after* bitbake.conf and any includes | 
|  | 416 | for p in postfiles: | 
|  | 417 | data = parse_config_file(p, data) | 
|  | 418 |  | 
|  | 419 | # Handle any INHERITs and inherit the base class | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 420 | bbclasses  = ["base"] + (data.getVar('INHERIT') or "").split() | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 421 | for bbclass in bbclasses: | 
|  | 422 | data = _inherit(bbclass, data) | 
|  | 423 |  | 
|  | 424 | # Nomally we only register event handlers at the end of parsing .bb files | 
|  | 425 | # We register any handlers we've found so far here... | 
|  | 426 | for var in data.getVar('__BBHANDLERS', False) or []: | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 427 | handlerfn = data.getVarFlag(var, "filename", False) | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 428 | if not handlerfn: | 
|  | 429 | parselog.critical("Undefined event handler function '%s'" % var) | 
|  | 430 | sys.exit(1) | 
| Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 431 | handlerln = int(data.getVarFlag(var, "lineno", False)) | 
| Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 432 | bb.event.register(var, data.getVar(var, False),  (data.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 433 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 434 | data.setVar('BBINCLUDED',bb.parse.get_file_depends(data)) | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 435 |  | 
| Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 436 | return data | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 437 |  |