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): |
Andrew Geissler | 6ce62a2 | 2020-11-30 19:58:47 -0600 | [diff] [blame] | 26 | def __init__(self, argv=None): |
| 27 | self.options, targets = self.parseCommandLine(argv or sys.argv) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 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 = {} |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 60 | for o in ["halt", "force", "invalidate_stamp", |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 61 | "dry_run", "dump_signatures", |
| 62 | "extra_assume_provided", "profile", |
| 63 | "prefile", "postfile", "server_timeout", |
| 64 | "nosetscene", "setsceneonly", "skipsetscene", |
| 65 | "runall", "runonly", "writeeventlog"]: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 66 | options[o] = getattr(self.options, o) |
| 67 | |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 68 | options['build_verbose_shell'] = self.options.verbose |
| 69 | options['build_verbose_stdout'] = self.options.verbose |
| 70 | options['default_loglevel'] = bb.msg.loggerDefaultLogLevel |
| 71 | options['debug_domains'] = bb.msg.loggerDefaultDomains |
| 72 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 73 | ret, error = server.runCommand(["updateConfig", options, environment, sys.argv]) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 74 | if error: |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 75 | 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] | 76 | |
| 77 | def parseActions(self): |
| 78 | # Parse any commandline into actions |
| 79 | action = {'action':None, 'msg':None} |
| 80 | if self.options.show_environment: |
| 81 | if 'world' in self.options.pkgs_to_build: |
| 82 | action['msg'] = "'world' is not a valid target for --environment." |
| 83 | elif 'universe' in self.options.pkgs_to_build: |
| 84 | action['msg'] = "'universe' is not a valid target for --environment." |
| 85 | elif len(self.options.pkgs_to_build) > 1: |
| 86 | action['msg'] = "Only one target can be used with the --environment option." |
| 87 | elif self.options.buildfile and len(self.options.pkgs_to_build) > 0: |
| 88 | action['msg'] = "No target should be used with the --environment and --buildfile options." |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 89 | elif self.options.pkgs_to_build: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 90 | action['action'] = ["showEnvironmentTarget", self.options.pkgs_to_build] |
| 91 | else: |
| 92 | action['action'] = ["showEnvironment", self.options.buildfile] |
| 93 | elif self.options.buildfile is not None: |
| 94 | action['action'] = ["buildFile", self.options.buildfile, self.options.cmd] |
| 95 | elif self.options.revisions_changed: |
| 96 | action['action'] = ["compareRevisions"] |
| 97 | elif self.options.show_versions: |
| 98 | action['action'] = ["showVersions"] |
| 99 | elif self.options.parse_only: |
| 100 | action['action'] = ["parseFiles"] |
| 101 | elif self.options.dot_graph: |
| 102 | if self.options.pkgs_to_build: |
| 103 | action['action'] = ["generateDotGraph", self.options.pkgs_to_build, self.options.cmd] |
| 104 | else: |
| 105 | action['msg'] = "Please specify a package name for dependency graph generation." |
| 106 | else: |
| 107 | if self.options.pkgs_to_build: |
| 108 | action['action'] = ["buildTargets", self.options.pkgs_to_build, self.options.cmd] |
| 109 | else: |
| 110 | #action['msg'] = "Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information." |
| 111 | action = None |
| 112 | self.options.initialaction = action |
| 113 | return action |
| 114 | |
| 115 | class CookerConfiguration(object): |
| 116 | """ |
| 117 | Manages build options and configurations for one run |
| 118 | """ |
| 119 | |
| 120 | def __init__(self): |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 121 | self.debug_domains = bb.msg.loggerDefaultDomains |
| 122 | self.default_loglevel = bb.msg.loggerDefaultLogLevel |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 123 | self.extra_assume_provided = [] |
| 124 | self.prefile = [] |
| 125 | self.postfile = [] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 126 | self.cmd = None |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 127 | self.halt = True |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 128 | self.force = False |
| 129 | self.profile = False |
| 130 | self.nosetscene = False |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 131 | self.setsceneonly = False |
Brad Bishop | 96ff198 | 2019-08-19 13:50:42 -0400 | [diff] [blame] | 132 | self.skipsetscene = False |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 133 | self.invalidate_stamp = False |
| 134 | self.dump_signatures = [] |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 135 | self.build_verbose_shell = False |
| 136 | self.build_verbose_stdout = False |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 137 | self.dry_run = False |
| 138 | self.tracking = False |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 139 | self.writeeventlog = False |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 140 | self.limited_deps = False |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 141 | self.runall = [] |
| 142 | self.runonly = [] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 143 | |
| 144 | self.env = {} |
| 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) |
Andrew Geissler | 6aa7eec | 2023-03-03 12:41:14 -0600 | [diff] [blame] | 163 | except Exception as exc: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 164 | import traceback |
| 165 | |
| 166 | bbdir = os.path.dirname(__file__) + os.sep |
| 167 | exc_class, exc, tb = sys.exc_info() |
| 168 | for tb in iter(lambda: tb.tb_next, None): |
| 169 | # Skip frames in bitbake itself, we only want the metadata |
| 170 | fn, _, _, _ = traceback.extract_tb(tb, 1)[0] |
| 171 | if not fn.startswith(bbdir): |
| 172 | break |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 173 | parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb)) |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 174 | raise bb.BBHandledException() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 175 | return wrapped |
| 176 | |
| 177 | @catch_parse_error |
| 178 | def parse_config_file(fn, data, include=True): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 179 | return bb.parse.handle(fn, data, include, baseconfig=True) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 180 | |
| 181 | @catch_parse_error |
| 182 | def _inherit(bbclass, data): |
| 183 | bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data) |
| 184 | return data |
| 185 | |
| 186 | def findConfigFile(configfile, data): |
| 187 | search = [] |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 188 | bbpath = data.getVar("BBPATH") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 189 | if bbpath: |
| 190 | for i in bbpath.split(":"): |
| 191 | search.append(os.path.join(i, "conf", configfile)) |
| 192 | path = os.getcwd() |
| 193 | while path != "/": |
| 194 | search.append(os.path.join(path, "conf", configfile)) |
| 195 | path, _ = os.path.split(path) |
| 196 | |
| 197 | for i in search: |
| 198 | if os.path.exists(i): |
| 199 | return i |
| 200 | |
| 201 | return None |
| 202 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 203 | # |
Andrew Geissler | 6ce62a2 | 2020-11-30 19:58:47 -0600 | [diff] [blame] | 204 | # We search for a conf/bblayers.conf under an entry in BBPATH or in cwd working |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 205 | # up to /. If that fails, bitbake would fall back to cwd. |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 206 | # |
| 207 | |
| 208 | def findTopdir(): |
| 209 | d = bb.data.init() |
| 210 | bbpath = None |
| 211 | if 'BBPATH' in os.environ: |
| 212 | bbpath = os.environ['BBPATH'] |
| 213 | d.setVar('BBPATH', bbpath) |
| 214 | |
| 215 | layerconf = findConfigFile("bblayers.conf", d) |
| 216 | if layerconf: |
| 217 | return os.path.dirname(os.path.dirname(layerconf)) |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 218 | |
| 219 | return os.path.abspath(os.getcwd()) |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 220 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 221 | class CookerDataBuilder(object): |
| 222 | |
| 223 | def __init__(self, cookercfg, worker = False): |
| 224 | |
| 225 | self.prefiles = cookercfg.prefile |
| 226 | self.postfiles = cookercfg.postfile |
| 227 | self.tracking = cookercfg.tracking |
| 228 | |
| 229 | bb.utils.set_context(bb.utils.clean_context()) |
| 230 | bb.event.set_class_handlers(bb.event.clean_class_handlers()) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 231 | self.basedata = bb.data.init() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 232 | if self.tracking: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 233 | self.basedata.enableTracking() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 234 | |
| 235 | # Keep a datastore of the initial environment variables and their |
| 236 | # values from when BitBake was launched to enable child processes |
| 237 | # to use environment variables which have been cleaned from the |
| 238 | # BitBake processes env |
| 239 | self.savedenv = bb.data.init() |
| 240 | for k in cookercfg.env: |
| 241 | self.savedenv.setVar(k, cookercfg.env[k]) |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 242 | if k in bb.data_smart.bitbake_renamed_vars: |
Andrew Geissler | d583833 | 2022-05-27 11:33:10 -0500 | [diff] [blame] | 243 | bb.error('Shell environment variable %s has been renamed to %s' % (k, bb.data_smart.bitbake_renamed_vars[k])) |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 244 | bb.fatal("Exiting to allow enviroment variables to be corrected") |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 245 | |
| 246 | filtered_keys = bb.utils.approved_variables() |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 247 | bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys) |
| 248 | self.basedata.setVar("BB_ORIGENV", self.savedenv) |
Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 249 | self.basedata.setVar("__bbclasstype", "global") |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 250 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 251 | if worker: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 252 | self.basedata.setVar("BB_WORKERCONTEXT", "1") |
| 253 | |
| 254 | self.data = self.basedata |
| 255 | self.mcdata = {} |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 256 | |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 257 | def parseBaseConfiguration(self, worker=False): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 258 | mcdata = {} |
Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 259 | data_hash = hashlib.sha256() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 260 | try: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 261 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) |
| 262 | |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 263 | if self.data.getVar("BB_WORKERCONTEXT", False) is None and not worker: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 264 | bb.fetch.fetcher_init(self.data) |
Brad Bishop | c68388fc | 2019-08-26 01:33:31 -0400 | [diff] [blame] | 265 | bb.parse.init_parser(self.data) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 266 | |
| 267 | bb.event.fire(bb.event.ConfigParsed(), self.data) |
| 268 | |
| 269 | reparse_cnt = 0 |
| 270 | while self.data.getVar("BB_INVALIDCONF", False) is True: |
| 271 | if reparse_cnt > 20: |
| 272 | logger.error("Configuration has been re-parsed over 20 times, " |
| 273 | "breaking out of the loop...") |
| 274 | raise Exception("Too deep config re-parse loop. Check locations where " |
| 275 | "BB_INVALIDCONF is being set (ConfigParsed event handlers)") |
| 276 | self.data.setVar("BB_INVALIDCONF", False) |
| 277 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) |
| 278 | reparse_cnt += 1 |
| 279 | bb.event.fire(bb.event.ConfigParsed(), self.data) |
| 280 | |
| 281 | bb.parse.init_parser(self.data) |
Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 282 | data_hash.update(self.data.get_hash().encode('utf-8')) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 283 | mcdata[''] = self.data |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 284 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 285 | multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split() |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 286 | for config in multiconfig: |
Andrew Geissler | 5199d83 | 2021-09-24 16:47:35 -0500 | [diff] [blame] | 287 | if config[0].isdigit(): |
| 288 | bb.fatal("Multiconfig name '%s' is invalid as multiconfigs cannot start with a digit" % config) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 289 | parsed_mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config) |
| 290 | bb.event.fire(bb.event.ConfigParsed(), parsed_mcdata) |
| 291 | mcdata[config] = parsed_mcdata |
| 292 | data_hash.update(parsed_mcdata.get_hash().encode('utf-8')) |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 293 | if multiconfig: |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 294 | bb.event.fire(bb.event.MultiConfigParsed(mcdata), self.data) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 295 | |
Brad Bishop | 00e122a | 2019-10-05 11:10:57 -0400 | [diff] [blame] | 296 | self.data_hash = data_hash.hexdigest() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 297 | except bb.data_smart.ExpansionError as e: |
| 298 | logger.error(str(e)) |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 299 | raise bb.BBHandledException() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 300 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 301 | bb.codeparser.update_module_dependencies(self.data) |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 302 | |
| 303 | # Handle obsolete variable names |
| 304 | d = self.data |
| 305 | renamedvars = d.getVarFlags('BB_RENAMED_VARIABLES') or {} |
| 306 | renamedvars.update(bb.data_smart.bitbake_renamed_vars) |
| 307 | issues = False |
| 308 | for v in renamedvars: |
| 309 | if d.getVar(v) != None or d.hasOverrides(v): |
| 310 | issues = True |
| 311 | loginfo = {} |
| 312 | history = d.varhistory.get_variable_refs(v) |
| 313 | for h in history: |
| 314 | for line in history[h]: |
| 315 | loginfo = {'file' : h, 'line' : line} |
| 316 | bb.data.data_smart._print_rename_error(v, loginfo, renamedvars) |
| 317 | if not history: |
| 318 | bb.data.data_smart._print_rename_error(v, loginfo, renamedvars) |
| 319 | if issues: |
| 320 | raise bb.BBHandledException() |
| 321 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 322 | for mc in mcdata: |
| 323 | mcdata[mc].renameVar("__depends", "__base_depends") |
| 324 | mcdata[mc].setVar("__bbclasstype", "recipe") |
| 325 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 326 | # Create a copy so we can reset at a later date when UIs disconnect |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 327 | self.mcorigdata = mcdata |
| 328 | for mc in mcdata: |
| 329 | self.mcdata[mc] = bb.data.createCopy(mcdata[mc]) |
| 330 | self.data = self.mcdata[''] |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 331 | |
| 332 | def reset(self): |
| 333 | # We may not have run parseBaseConfiguration() yet |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 334 | if not hasattr(self, 'mcorigdata'): |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 335 | return |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 336 | for mc in self.mcorigdata: |
| 337 | self.mcdata[mc] = bb.data.createCopy(self.mcorigdata[mc]) |
| 338 | self.data = self.mcdata[''] |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 339 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 340 | def _findLayerConf(self, data): |
| 341 | return findConfigFile("bblayers.conf", data) |
| 342 | |
Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 343 | def parseConfigurationFiles(self, prefiles, postfiles, mc = "default"): |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 344 | data = bb.data.createCopy(self.basedata) |
Brad Bishop | 37a0e4d | 2017-12-04 01:01:44 -0500 | [diff] [blame] | 345 | data.setVar("BB_CURRENT_MC", mc) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 346 | |
| 347 | # Parse files for loading *before* bitbake.conf and any includes |
| 348 | for f in prefiles: |
| 349 | data = parse_config_file(f, data) |
| 350 | |
| 351 | layerconf = self._findLayerConf(data) |
| 352 | if layerconf: |
Andrew Geissler | 87f5cff | 2022-09-30 13:13:31 -0500 | [diff] [blame] | 353 | parselog.debug2("Found bblayers.conf (%s)", layerconf) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 354 | # By definition bblayers.conf is in conf/ of TOPDIR. |
| 355 | # We may have been called with cwd somewhere else so reset TOPDIR |
| 356 | data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf))) |
| 357 | data = parse_config_file(layerconf, data) |
| 358 | |
Andrew Geissler | c5535c9 | 2023-01-27 16:10:19 -0600 | [diff] [blame] | 359 | if not data.getVar("BB_CACHEDIR"): |
| 360 | data.setVar("BB_CACHEDIR", "${TOPDIR}/cache") |
| 361 | |
| 362 | bb.codeparser.parser_cache_init(data.getVar("BB_CACHEDIR")) |
| 363 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 364 | layers = (data.getVar('BBLAYERS') or "").split() |
Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 365 | broken_layers = [] |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 366 | |
Andrew Geissler | 5199d83 | 2021-09-24 16:47:35 -0500 | [diff] [blame] | 367 | if not layers: |
| 368 | bb.fatal("The bblayers.conf file doesn't contain any BBLAYERS definition") |
| 369 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 370 | data = bb.data.createCopy(data) |
| 371 | approved = bb.utils.approved_variables() |
Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 372 | |
| 373 | # Check whether present layer directories exist |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 374 | for layer in layers: |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 375 | if not os.path.isdir(layer): |
Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 376 | broken_layers.append(layer) |
| 377 | |
| 378 | if broken_layers: |
| 379 | parselog.critical("The following layer directories do not exist:") |
| 380 | for layer in broken_layers: |
| 381 | parselog.critical(" %s", layer) |
| 382 | parselog.critical("Please check BBLAYERS in %s" % (layerconf)) |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 383 | raise bb.BBHandledException() |
Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 384 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 385 | layerseries = None |
| 386 | compat_entries = {} |
Brad Bishop | 15ae250 | 2019-06-18 21:44:24 -0400 | [diff] [blame] | 387 | for layer in layers: |
Andrew Geissler | 87f5cff | 2022-09-30 13:13:31 -0500 | [diff] [blame] | 388 | parselog.debug2("Adding layer %s", layer) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 389 | if 'HOME' in approved and '~' in layer: |
| 390 | layer = os.path.expanduser(layer) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 391 | if layer.endswith('/'): |
| 392 | layer = layer.rstrip('/') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 393 | data.setVar('LAYERDIR', layer) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 394 | data.setVar('LAYERDIR_RE', re.escape(layer)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 395 | data = parse_config_file(os.path.join(layer, "conf", "layer.conf"), data) |
| 396 | data.expandVarref('LAYERDIR') |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 397 | data.expandVarref('LAYERDIR_RE') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 398 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 399 | # Sadly we can't have nice things. |
| 400 | # Some layers think they're going to be 'clever' and copy the values from |
| 401 | # another layer, e.g. using ${LAYERSERIES_COMPAT_core}. The whole point of |
| 402 | # this mechanism is to make it clear which releases a layer supports and |
| 403 | # show when a layer master branch is bitrotting and is unmaintained. |
| 404 | # We therefore avoid people doing this here. |
| 405 | collections = (data.getVar('BBFILE_COLLECTIONS') or "").split() |
| 406 | for c in collections: |
| 407 | compat_entry = data.getVar("LAYERSERIES_COMPAT_%s" % c) |
| 408 | if compat_entry: |
| 409 | compat_entries[c] = set(compat_entry.split()) |
| 410 | data.delVar("LAYERSERIES_COMPAT_%s" % c) |
| 411 | if not layerseries: |
| 412 | layerseries = set((data.getVar("LAYERSERIES_CORENAMES") or "").split()) |
| 413 | if layerseries: |
| 414 | data.delVar("LAYERSERIES_CORENAMES") |
| 415 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 416 | data.delVar('LAYERDIR_RE') |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 417 | data.delVar('LAYERDIR') |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 418 | for c in compat_entries: |
| 419 | data.setVar("LAYERSERIES_COMPAT_%s" % c, " ".join(sorted(compat_entries[c]))) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 420 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 421 | bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split() |
| 422 | collections = (data.getVar('BBFILE_COLLECTIONS') or "").split() |
| 423 | invalid = [] |
| 424 | for entry in bbfiles_dynamic: |
| 425 | parts = entry.split(":", 1) |
| 426 | if len(parts) != 2: |
| 427 | invalid.append(entry) |
| 428 | continue |
| 429 | l, f = parts |
Andrew Geissler | d25ed32 | 2020-06-27 00:28:28 -0500 | [diff] [blame] | 430 | invert = l[0] == "!" |
| 431 | if invert: |
| 432 | l = l[1:] |
| 433 | 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] | 434 | data.appendVar("BBFILES", " " + f) |
| 435 | if invalid: |
Andrew Geissler | d25ed32 | 2020-06-27 00:28:28 -0500 | [diff] [blame] | 436 | 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] | 437 | |
Brad Bishop | 1932369 | 2019-04-05 15:28:33 -0400 | [diff] [blame] | 438 | collections_tmp = collections[:] |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 439 | for c in collections: |
Brad Bishop | 1932369 | 2019-04-05 15:28:33 -0400 | [diff] [blame] | 440 | collections_tmp.remove(c) |
| 441 | if c in collections_tmp: |
| 442 | bb.fatal("Found duplicated BBFILE_COLLECTIONS '%s', check bblayers.conf or layer.conf to fix it." % c) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 443 | |
| 444 | compat = set() |
| 445 | if c in compat_entries: |
| 446 | compat = compat_entries[c] |
Andrew Geissler | 5199d83 | 2021-09-24 16:47:35 -0500 | [diff] [blame] | 447 | if compat and not layerseries: |
| 448 | bb.fatal("No core layer found to work with layer '%s'. Missing entry in bblayers.conf?" % c) |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 449 | if compat and not (compat & layerseries): |
| 450 | bb.fatal("Layer %s is not compatible with the core layer which only supports these series: %s (layer is compatible with %s)" |
| 451 | % (c, " ".join(layerseries), " ".join(compat))) |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 452 | elif not compat and not data.getVar("BB_WORKERCONTEXT"): |
| 453 | 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] | 454 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 455 | data.setVar("LAYERSERIES_CORENAMES", " ".join(sorted(layerseries))) |
| 456 | |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 457 | if not data.getVar("BBPATH"): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 458 | msg = "The BBPATH variable is not set" |
| 459 | if not layerconf: |
| 460 | msg += (" and bitbake did not find a conf/bblayers.conf file in" |
| 461 | " the expected location.\nMaybe you accidentally" |
| 462 | " invoked bitbake from the wrong directory?") |
Andrew Geissler | 6aa7eec | 2023-03-03 12:41:14 -0600 | [diff] [blame] | 463 | bb.fatal(msg) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 464 | |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 465 | if not data.getVar("TOPDIR"): |
| 466 | data.setVar("TOPDIR", os.path.abspath(os.getcwd())) |
Andrew Geissler | c5535c9 | 2023-01-27 16:10:19 -0600 | [diff] [blame] | 467 | if not data.getVar("BB_CACHEDIR"): |
| 468 | data.setVar("BB_CACHEDIR", "${TOPDIR}/cache") |
| 469 | bb.codeparser.parser_cache_init(data.getVar("BB_CACHEDIR")) |
Andrew Geissler | 595f630 | 2022-01-24 19:11:47 +0000 | [diff] [blame] | 470 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 471 | data = parse_config_file(os.path.join("conf", "bitbake.conf"), data) |
| 472 | |
| 473 | # Parse files for loading *after* bitbake.conf and any includes |
| 474 | for p in postfiles: |
| 475 | data = parse_config_file(p, data) |
| 476 | |
| 477 | # Handle any INHERITs and inherit the base class |
Brad Bishop | 6e60e8b | 2018-02-01 10:27:11 -0500 | [diff] [blame] | 478 | bbclasses = ["base"] + (data.getVar('INHERIT') or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 479 | for bbclass in bbclasses: |
| 480 | data = _inherit(bbclass, data) |
| 481 | |
Andrew Geissler | 7e0e3c0 | 2022-02-25 20:34:39 +0000 | [diff] [blame] | 482 | # Normally we only register event handlers at the end of parsing .bb files |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 483 | # We register any handlers we've found so far here... |
| 484 | for var in data.getVar('__BBHANDLERS', False) or []: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 485 | handlerfn = data.getVarFlag(var, "filename", False) |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 486 | if not handlerfn: |
| 487 | parselog.critical("Undefined event handler function '%s'" % var) |
Andrew Geissler | c9f7865 | 2020-09-18 14:11:35 -0500 | [diff] [blame] | 488 | raise bb.BBHandledException() |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 489 | handlerln = int(data.getVarFlag(var, "lineno", False)) |
Andrew Geissler | 9b4d8b0 | 2021-02-19 12:26:16 -0600 | [diff] [blame] | 490 | bb.event.register(var, data.getVar(var, False), (data.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln, data) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 491 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 492 | data.setVar('BBINCLUDED',bb.parse.get_file_depends(data)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 493 | |
Patrick Williams | c0f7c04 | 2017-02-23 20:41:17 -0600 | [diff] [blame] | 494 | return data |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 495 | |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 496 | @staticmethod |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 497 | def _parse_recipe(bb_data, bbfile, appends, mc, layername): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 498 | bb_data.setVar("__BBMULTICONFIG", mc) |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 499 | bb_data.setVar("FILE_LAYERNAME", layername) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 500 | |
| 501 | bbfile_loc = os.path.abspath(os.path.dirname(bbfile)) |
| 502 | bb.parse.cached_mtime_noerror(bbfile_loc) |
| 503 | |
| 504 | if appends: |
| 505 | bb_data.setVar('__BBAPPEND', " ".join(appends)) |
Patrick Williams | ac13d5f | 2023-11-24 18:59:46 -0600 | [diff] [blame] | 506 | |
| 507 | return bb.parse.handle(bbfile, bb_data) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 508 | |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 509 | def parseRecipeVariants(self, bbfile, appends, virtonly=False, mc=None, layername=None): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 510 | """ |
| 511 | Load and parse one .bb build file |
| 512 | Return the data and whether parsing resulted in the file being skipped |
| 513 | """ |
| 514 | |
| 515 | if virtonly: |
| 516 | (bbfile, virtual, mc) = bb.cache.virtualfn2realfn(bbfile) |
| 517 | bb_data = self.mcdata[mc].createCopy() |
| 518 | bb_data.setVar("__ONLYFINALISE", virtual or "default") |
Patrick Williams | ac13d5f | 2023-11-24 18:59:46 -0600 | [diff] [blame] | 519 | return self._parse_recipe(bb_data, bbfile, appends, mc, layername) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 520 | |
| 521 | if mc is not None: |
| 522 | bb_data = self.mcdata[mc].createCopy() |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 523 | return self._parse_recipe(bb_data, bbfile, appends, mc, layername) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 524 | |
| 525 | bb_data = self.data.createCopy() |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 526 | datastores = self._parse_recipe(bb_data, bbfile, appends, '', layername) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 527 | |
| 528 | for mc in self.mcdata: |
| 529 | if not mc: |
| 530 | continue |
| 531 | bb_data = self.mcdata[mc].createCopy() |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 532 | newstores = self._parse_recipe(bb_data, bbfile, appends, mc, layername) |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 533 | for ns in newstores: |
| 534 | datastores["mc:%s:%s" % (mc, ns)] = newstores[ns] |
| 535 | |
| 536 | return datastores |
| 537 | |
Patrick Williams | e760df8 | 2023-05-26 11:10:49 -0500 | [diff] [blame] | 538 | def parseRecipe(self, virtualfn, appends, layername): |
Andrew Geissler | 517393d | 2023-01-13 08:55:19 -0600 | [diff] [blame] | 539 | """ |
| 540 | Return a complete set of data for fn. |
| 541 | To do this, we need to parse the file. |
| 542 | """ |
| 543 | logger.debug("Parsing %s (full)" % virtualfn) |
| 544 | (fn, virtual, mc) = bb.cache.virtualfn2realfn(virtualfn) |
Patrick Williams | ac13d5f | 2023-11-24 18:59:46 -0600 | [diff] [blame] | 545 | datastores = self.parseRecipeVariants(virtualfn, appends, virtonly=True, layername=layername) |
| 546 | return datastores[virtual] |