blob: 1658bee93c15aed08b26c6636e2567760618ce50 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
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 Bishopc342db32019-05-15 21:57:59 -04009# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050010#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012import logging
Patrick Williamsc0f7c042017-02-23 20:41:17 -060013import os
14import re
15import sys
Brad Bishop00e122a2019-10-05 11:10:57 -040016import hashlib
Patrick Williamsc0f7c042017-02-23 20:41:17 -060017from functools import wraps
Patrick Williamsc124f4f2015-09-15 14:41:29 -050018import bb
19from bb import data
20import bb.parse
21
22logger = logging.getLogger("BitBake")
23parselog = logging.getLogger("BitBake.Parsing")
24
25class ConfigParameters(object):
Andrew Geissler6ce62a22020-11-30 19:58:47 -060026 def __init__(self, argv=None):
27 self.options, targets = self.parseCommandLine(argv or sys.argv)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028 self.environment = self.parseEnvironment()
29
30 self.options.pkgs_to_build = targets or []
31
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032 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 Williamsf1e5d692016-03-30 15:21:19 -050052 bbpkgs, error = server.runCommand(["getVariable", "BBTARGETS"])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050053 if error:
Patrick Williamsf1e5d692016-03-30 15:21:19 -050054 raise Exception("Unable to get the value of BBTARGETS from the server: %s" % error)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050055 if bbpkgs:
56 self.options.pkgs_to_build.extend(bbpkgs.split())
57
58 def updateToServer(self, server, environment):
59 options = {}
Andrew Geissler7e0e3c02022-02-25 20:34:39 +000060 for o in ["halt", "force", "invalidate_stamp",
Andrew Geisslerc9f78652020-09-18 14:11:35 -050061 "dry_run", "dump_signatures",
62 "extra_assume_provided", "profile",
63 "prefile", "postfile", "server_timeout",
64 "nosetscene", "setsceneonly", "skipsetscene",
65 "runall", "runonly", "writeeventlog"]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050066 options[o] = getattr(self.options, o)
67
Andrew Geisslerc9f78652020-09-18 14:11:35 -050068 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 Bishop6e60e8b2018-02-01 10:27:11 -050073 ret, error = server.runCommand(["updateConfig", options, environment, sys.argv])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 if error:
Brad Bishopd7bf8c12018-02-25 22:55:05 -050075 raise Exception("Unable to update the server configuration with local parameters: %s" % error)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076
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 Geissler595f6302022-01-24 19:11:47 +000089 elif self.options.pkgs_to_build:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050090 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
115class CookerConfiguration(object):
116 """
117 Manages build options and configurations for one run
118 """
119
120 def __init__(self):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500121 self.debug_domains = bb.msg.loggerDefaultDomains
122 self.default_loglevel = bb.msg.loggerDefaultLogLevel
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123 self.extra_assume_provided = []
124 self.prefile = []
125 self.postfile = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500126 self.cmd = None
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000127 self.halt = True
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500128 self.force = False
129 self.profile = False
130 self.nosetscene = False
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500131 self.setsceneonly = False
Brad Bishop96ff1982019-08-19 13:50:42 -0400132 self.skipsetscene = False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500133 self.invalidate_stamp = False
134 self.dump_signatures = []
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500135 self.build_verbose_shell = False
136 self.build_verbose_stdout = False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500137 self.dry_run = False
138 self.tracking = False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500139 self.writeeventlog = False
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500140 self.limited_deps = False
Brad Bishop316dfdd2018-06-25 12:45:53 -0400141 self.runall = []
142 self.runonly = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143
144 self.env = {}
145
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500146 def __getstate__(self):
147 state = {}
148 for key in self.__dict__.keys():
Andrew Geissler635e0e42020-08-21 15:58:33 -0500149 state[key] = getattr(self, key)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500150 return state
151
152 def __setstate__(self,state):
153 for k in state:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500154 setattr(self, k, state[k])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155
156
157def 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))
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500167 raise bb.BBHandledException()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500168 except bb.data_smart.ExpansionError as exc:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500169 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 Williamsc0f7c042017-02-23 20:41:17 -0600178 parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb))
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500179 raise bb.BBHandledException()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500180 except bb.parse.ParseError as exc:
181 parselog.critical(str(exc))
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500182 raise bb.BBHandledException()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500183 return wrapped
184
185@catch_parse_error
186def parse_config_file(fn, data, include=True):
Andrew Geissler517393d2023-01-13 08:55:19 -0600187 return bb.parse.handle(fn, data, include, baseconfig=True)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500188
189@catch_parse_error
190def _inherit(bbclass, data):
191 bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
192 return data
193
194def findConfigFile(configfile, data):
195 search = []
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500196 bbpath = data.getVar("BBPATH")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500197 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 Bishopd7bf8c12018-02-25 22:55:05 -0500211#
Andrew Geissler6ce62a22020-11-30 19:58:47 -0600212# We search for a conf/bblayers.conf under an entry in BBPATH or in cwd working
Andrew Geissler595f6302022-01-24 19:11:47 +0000213# up to /. If that fails, bitbake would fall back to cwd.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500214#
215
216def 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))
Andrew Geissler595f6302022-01-24 19:11:47 +0000226
227 return os.path.abspath(os.getcwd())
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500228
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229class CookerDataBuilder(object):
230
231 def __init__(self, cookercfg, worker = False):
232
233 self.prefiles = cookercfg.prefile
234 self.postfiles = cookercfg.postfile
235 self.tracking = cookercfg.tracking
236
237 bb.utils.set_context(bb.utils.clean_context())
238 bb.event.set_class_handlers(bb.event.clean_class_handlers())
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600239 self.basedata = bb.data.init()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500240 if self.tracking:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600241 self.basedata.enableTracking()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242
243 # Keep a datastore of the initial environment variables and their
244 # values from when BitBake was launched to enable child processes
245 # to use environment variables which have been cleaned from the
246 # BitBake processes env
247 self.savedenv = bb.data.init()
248 for k in cookercfg.env:
249 self.savedenv.setVar(k, cookercfg.env[k])
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000250 if k in bb.data_smart.bitbake_renamed_vars:
Andrew Geisslerd5838332022-05-27 11:33:10 -0500251 bb.error('Shell environment variable %s has been renamed to %s' % (k, bb.data_smart.bitbake_renamed_vars[k]))
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000252 bb.fatal("Exiting to allow enviroment variables to be corrected")
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500253
254 filtered_keys = bb.utils.approved_variables()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600255 bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys)
256 self.basedata.setVar("BB_ORIGENV", self.savedenv)
Patrick Williams92b42cb2022-09-03 06:53:57 -0500257 self.basedata.setVar("__bbclasstype", "global")
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500258
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500259 if worker:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600260 self.basedata.setVar("BB_WORKERCONTEXT", "1")
261
262 self.data = self.basedata
263 self.mcdata = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500264
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000265 def parseBaseConfiguration(self, worker=False):
Andrew Geissler517393d2023-01-13 08:55:19 -0600266 mcdata = {}
Brad Bishop00e122a2019-10-05 11:10:57 -0400267 data_hash = hashlib.sha256()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500268 try:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600269 self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles)
270
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000271 if self.data.getVar("BB_WORKERCONTEXT", False) is None and not worker:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600272 bb.fetch.fetcher_init(self.data)
Brad Bishopc68388fc2019-08-26 01:33:31 -0400273 bb.parse.init_parser(self.data)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600274
275 bb.event.fire(bb.event.ConfigParsed(), self.data)
276
277 reparse_cnt = 0
278 while self.data.getVar("BB_INVALIDCONF", False) is True:
279 if reparse_cnt > 20:
280 logger.error("Configuration has been re-parsed over 20 times, "
281 "breaking out of the loop...")
282 raise Exception("Too deep config re-parse loop. Check locations where "
283 "BB_INVALIDCONF is being set (ConfigParsed event handlers)")
284 self.data.setVar("BB_INVALIDCONF", False)
285 self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles)
286 reparse_cnt += 1
287 bb.event.fire(bb.event.ConfigParsed(), self.data)
288
289 bb.parse.init_parser(self.data)
Brad Bishop00e122a2019-10-05 11:10:57 -0400290 data_hash.update(self.data.get_hash().encode('utf-8'))
Andrew Geissler517393d2023-01-13 08:55:19 -0600291 mcdata[''] = self.data
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600292
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500293 multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600294 for config in multiconfig:
Andrew Geissler5199d832021-09-24 16:47:35 -0500295 if config[0].isdigit():
296 bb.fatal("Multiconfig name '%s' is invalid as multiconfigs cannot start with a digit" % config)
Andrew Geissler517393d2023-01-13 08:55:19 -0600297 parsed_mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config)
298 bb.event.fire(bb.event.ConfigParsed(), parsed_mcdata)
299 mcdata[config] = parsed_mcdata
300 data_hash.update(parsed_mcdata.get_hash().encode('utf-8'))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500301 if multiconfig:
Andrew Geissler517393d2023-01-13 08:55:19 -0600302 bb.event.fire(bb.event.MultiConfigParsed(mcdata), self.data)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600303
Brad Bishop00e122a2019-10-05 11:10:57 -0400304 self.data_hash = data_hash.hexdigest()
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600305 except (SyntaxError, bb.BBHandledException):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500306 raise bb.BBHandledException()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500307 except bb.data_smart.ExpansionError as e:
308 logger.error(str(e))
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500309 raise bb.BBHandledException()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500310 except Exception:
311 logger.exception("Error parsing configuration files")
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500312 raise bb.BBHandledException()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500313
Andrew Geissler517393d2023-01-13 08:55:19 -0600314 bb.codeparser.update_module_dependencies(self.data)
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000315
316 # Handle obsolete variable names
317 d = self.data
318 renamedvars = d.getVarFlags('BB_RENAMED_VARIABLES') or {}
319 renamedvars.update(bb.data_smart.bitbake_renamed_vars)
320 issues = False
321 for v in renamedvars:
322 if d.getVar(v) != None or d.hasOverrides(v):
323 issues = True
324 loginfo = {}
325 history = d.varhistory.get_variable_refs(v)
326 for h in history:
327 for line in history[h]:
328 loginfo = {'file' : h, 'line' : line}
329 bb.data.data_smart._print_rename_error(v, loginfo, renamedvars)
330 if not history:
331 bb.data.data_smart._print_rename_error(v, loginfo, renamedvars)
332 if issues:
333 raise bb.BBHandledException()
334
Andrew Geissler517393d2023-01-13 08:55:19 -0600335 for mc in mcdata:
336 mcdata[mc].renameVar("__depends", "__base_depends")
337 mcdata[mc].setVar("__bbclasstype", "recipe")
338
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500339 # Create a copy so we can reset at a later date when UIs disconnect
Andrew Geissler517393d2023-01-13 08:55:19 -0600340 self.mcorigdata = mcdata
341 for mc in mcdata:
342 self.mcdata[mc] = bb.data.createCopy(mcdata[mc])
343 self.data = self.mcdata['']
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500344
345 def reset(self):
346 # We may not have run parseBaseConfiguration() yet
Andrew Geissler517393d2023-01-13 08:55:19 -0600347 if not hasattr(self, 'mcorigdata'):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500348 return
Andrew Geissler517393d2023-01-13 08:55:19 -0600349 for mc in self.mcorigdata:
350 self.mcdata[mc] = bb.data.createCopy(self.mcorigdata[mc])
351 self.data = self.mcdata['']
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500352
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500353 def _findLayerConf(self, data):
354 return findConfigFile("bblayers.conf", data)
355
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500356 def parseConfigurationFiles(self, prefiles, postfiles, mc = "default"):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600357 data = bb.data.createCopy(self.basedata)
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500358 data.setVar("BB_CURRENT_MC", mc)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500359
360 # Parse files for loading *before* bitbake.conf and any includes
361 for f in prefiles:
362 data = parse_config_file(f, data)
363
364 layerconf = self._findLayerConf(data)
365 if layerconf:
Andrew Geissler87f5cff2022-09-30 13:13:31 -0500366 parselog.debug2("Found bblayers.conf (%s)", layerconf)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500367 # By definition bblayers.conf is in conf/ of TOPDIR.
368 # We may have been called with cwd somewhere else so reset TOPDIR
369 data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf)))
370 data = parse_config_file(layerconf, data)
371
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600372 if not data.getVar("BB_CACHEDIR"):
373 data.setVar("BB_CACHEDIR", "${TOPDIR}/cache")
374
375 bb.codeparser.parser_cache_init(data.getVar("BB_CACHEDIR"))
376
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500377 layers = (data.getVar('BBLAYERS') or "").split()
Brad Bishop15ae2502019-06-18 21:44:24 -0400378 broken_layers = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500379
Andrew Geissler5199d832021-09-24 16:47:35 -0500380 if not layers:
381 bb.fatal("The bblayers.conf file doesn't contain any BBLAYERS definition")
382
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500383 data = bb.data.createCopy(data)
384 approved = bb.utils.approved_variables()
Brad Bishop15ae2502019-06-18 21:44:24 -0400385
386 # Check whether present layer directories exist
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500387 for layer in layers:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600388 if not os.path.isdir(layer):
Brad Bishop15ae2502019-06-18 21:44:24 -0400389 broken_layers.append(layer)
390
391 if broken_layers:
392 parselog.critical("The following layer directories do not exist:")
393 for layer in broken_layers:
394 parselog.critical(" %s", layer)
395 parselog.critical("Please check BBLAYERS in %s" % (layerconf))
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500396 raise bb.BBHandledException()
Brad Bishop15ae2502019-06-18 21:44:24 -0400397
Andrew Geissler517393d2023-01-13 08:55:19 -0600398 layerseries = None
399 compat_entries = {}
Brad Bishop15ae2502019-06-18 21:44:24 -0400400 for layer in layers:
Andrew Geissler87f5cff2022-09-30 13:13:31 -0500401 parselog.debug2("Adding layer %s", layer)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500402 if 'HOME' in approved and '~' in layer:
403 layer = os.path.expanduser(layer)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500404 if layer.endswith('/'):
405 layer = layer.rstrip('/')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500406 data.setVar('LAYERDIR', layer)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600407 data.setVar('LAYERDIR_RE', re.escape(layer))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500408 data = parse_config_file(os.path.join(layer, "conf", "layer.conf"), data)
409 data.expandVarref('LAYERDIR')
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600410 data.expandVarref('LAYERDIR_RE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500411
Andrew Geissler517393d2023-01-13 08:55:19 -0600412 # Sadly we can't have nice things.
413 # Some layers think they're going to be 'clever' and copy the values from
414 # another layer, e.g. using ${LAYERSERIES_COMPAT_core}. The whole point of
415 # this mechanism is to make it clear which releases a layer supports and
416 # show when a layer master branch is bitrotting and is unmaintained.
417 # We therefore avoid people doing this here.
418 collections = (data.getVar('BBFILE_COLLECTIONS') or "").split()
419 for c in collections:
420 compat_entry = data.getVar("LAYERSERIES_COMPAT_%s" % c)
421 if compat_entry:
422 compat_entries[c] = set(compat_entry.split())
423 data.delVar("LAYERSERIES_COMPAT_%s" % c)
424 if not layerseries:
425 layerseries = set((data.getVar("LAYERSERIES_CORENAMES") or "").split())
426 if layerseries:
427 data.delVar("LAYERSERIES_CORENAMES")
428
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600429 data.delVar('LAYERDIR_RE')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500430 data.delVar('LAYERDIR')
Andrew Geissler517393d2023-01-13 08:55:19 -0600431 for c in compat_entries:
432 data.setVar("LAYERSERIES_COMPAT_%s" % c, " ".join(sorted(compat_entries[c])))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500433
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500434 bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split()
435 collections = (data.getVar('BBFILE_COLLECTIONS') or "").split()
436 invalid = []
437 for entry in bbfiles_dynamic:
438 parts = entry.split(":", 1)
439 if len(parts) != 2:
440 invalid.append(entry)
441 continue
442 l, f = parts
Andrew Geisslerd25ed322020-06-27 00:28:28 -0500443 invert = l[0] == "!"
444 if invert:
445 l = l[1:]
446 if (l in collections and not invert) or (l not in collections and invert):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500447 data.appendVar("BBFILES", " " + f)
448 if invalid:
Andrew Geisslerd25ed322020-06-27 00:28:28 -0500449 bb.fatal("BBFILES_DYNAMIC entries must be of the form {!}<collection name>:<filename pattern>, not:\n %s" % "\n ".join(invalid))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500450
Brad Bishop19323692019-04-05 15:28:33 -0400451 collections_tmp = collections[:]
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500452 for c in collections:
Brad Bishop19323692019-04-05 15:28:33 -0400453 collections_tmp.remove(c)
454 if c in collections_tmp:
455 bb.fatal("Found duplicated BBFILE_COLLECTIONS '%s', check bblayers.conf or layer.conf to fix it." % c)
Andrew Geissler517393d2023-01-13 08:55:19 -0600456
457 compat = set()
458 if c in compat_entries:
459 compat = compat_entries[c]
Andrew Geissler5199d832021-09-24 16:47:35 -0500460 if compat and not layerseries:
461 bb.fatal("No core layer found to work with layer '%s'. Missing entry in bblayers.conf?" % c)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500462 if compat and not (compat & layerseries):
463 bb.fatal("Layer %s is not compatible with the core layer which only supports these series: %s (layer is compatible with %s)"
464 % (c, " ".join(layerseries), " ".join(compat)))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400465 elif not compat and not data.getVar("BB_WORKERCONTEXT"):
466 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 Bishopd7bf8c12018-02-25 22:55:05 -0500467
Andrew Geissler517393d2023-01-13 08:55:19 -0600468 data.setVar("LAYERSERIES_CORENAMES", " ".join(sorted(layerseries)))
469
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500470 if not data.getVar("BBPATH"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500471 msg = "The BBPATH variable is not set"
472 if not layerconf:
473 msg += (" and bitbake did not find a conf/bblayers.conf file in"
474 " the expected location.\nMaybe you accidentally"
475 " invoked bitbake from the wrong directory?")
476 raise SystemExit(msg)
477
Andrew Geissler595f6302022-01-24 19:11:47 +0000478 if not data.getVar("TOPDIR"):
479 data.setVar("TOPDIR", os.path.abspath(os.getcwd()))
Andrew Geisslerc5535c92023-01-27 16:10:19 -0600480 if not data.getVar("BB_CACHEDIR"):
481 data.setVar("BB_CACHEDIR", "${TOPDIR}/cache")
482 bb.codeparser.parser_cache_init(data.getVar("BB_CACHEDIR"))
Andrew Geissler595f6302022-01-24 19:11:47 +0000483
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500484 data = parse_config_file(os.path.join("conf", "bitbake.conf"), data)
485
486 # Parse files for loading *after* bitbake.conf and any includes
487 for p in postfiles:
488 data = parse_config_file(p, data)
489
490 # Handle any INHERITs and inherit the base class
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500491 bbclasses = ["base"] + (data.getVar('INHERIT') or "").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500492 for bbclass in bbclasses:
493 data = _inherit(bbclass, data)
494
Andrew Geissler7e0e3c02022-02-25 20:34:39 +0000495 # Normally we only register event handlers at the end of parsing .bb files
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500496 # We register any handlers we've found so far here...
497 for var in data.getVar('__BBHANDLERS', False) or []:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500498 handlerfn = data.getVarFlag(var, "filename", False)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600499 if not handlerfn:
500 parselog.critical("Undefined event handler function '%s'" % var)
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500501 raise bb.BBHandledException()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500502 handlerln = int(data.getVarFlag(var, "lineno", False))
Andrew Geissler9b4d8b02021-02-19 12:26:16 -0600503 bb.event.register(var, data.getVar(var, False), (data.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln, data)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500504
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500505 data.setVar('BBINCLUDED',bb.parse.get_file_depends(data))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500506
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600507 return data
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500508
Andrew Geissler517393d2023-01-13 08:55:19 -0600509 @staticmethod
510 def _parse_recipe(bb_data, bbfile, appends, mc=''):
511 bb_data.setVar("__BBMULTICONFIG", mc)
512
513 bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
514 bb.parse.cached_mtime_noerror(bbfile_loc)
515
516 if appends:
517 bb_data.setVar('__BBAPPEND', " ".join(appends))
518 bb_data = bb.parse.handle(bbfile, bb_data)
519 return bb_data
520
521 def parseRecipeVariants(self, bbfile, appends, virtonly=False, mc=None):
522 """
523 Load and parse one .bb build file
524 Return the data and whether parsing resulted in the file being skipped
525 """
526
527 if virtonly:
528 (bbfile, virtual, mc) = bb.cache.virtualfn2realfn(bbfile)
529 bb_data = self.mcdata[mc].createCopy()
530 bb_data.setVar("__ONLYFINALISE", virtual or "default")
531 datastores = self._parse_recipe(bb_data, bbfile, appends, mc)
532 return datastores
533
534 if mc is not None:
535 bb_data = self.mcdata[mc].createCopy()
536 return self._parse_recipe(bb_data, bbfile, appends, mc)
537
538 bb_data = self.data.createCopy()
539 datastores = self._parse_recipe(bb_data, bbfile, appends)
540
541 for mc in self.mcdata:
542 if not mc:
543 continue
544 bb_data = self.mcdata[mc].createCopy()
545 newstores = self._parse_recipe(bb_data, bbfile, appends, mc)
546 for ns in newstores:
547 datastores["mc:%s:%s" % (mc, ns)] = newstores[ns]
548
549 return datastores
550
551 def parseRecipe(self, virtualfn, appends):
552 """
553 Return a complete set of data for fn.
554 To do this, we need to parse the file.
555 """
556 logger.debug("Parsing %s (full)" % virtualfn)
557 (fn, virtual, mc) = bb.cache.virtualfn2realfn(virtualfn)
558 bb_data = self.parseRecipeVariants(virtualfn, appends, virtonly=True)
559 return bb_data[virtual]