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