diff options
Diffstat (limited to 'bitbake/lib/bb/cookerdata.py')
-rw-r--r-- | bitbake/lib/bb/cookerdata.py | 197 |
1 files changed, 153 insertions, 44 deletions
diff --git a/bitbake/lib/bb/cookerdata.py b/bitbake/lib/bb/cookerdata.py index 1c1e008c6b..0649e40995 100644 --- a/bitbake/lib/bb/cookerdata.py +++ b/bitbake/lib/bb/cookerdata.py | |||
@@ -57,7 +57,7 @@ class ConfigParameters(object): | |||
57 | 57 | ||
58 | def updateToServer(self, server, environment): | 58 | def updateToServer(self, server, environment): |
59 | options = {} | 59 | options = {} |
60 | for o in ["abort", "force", "invalidate_stamp", | 60 | for o in ["halt", "force", "invalidate_stamp", |
61 | "dry_run", "dump_signatures", | 61 | "dry_run", "dump_signatures", |
62 | "extra_assume_provided", "profile", | 62 | "extra_assume_provided", "profile", |
63 | "prefile", "postfile", "server_timeout", | 63 | "prefile", "postfile", "server_timeout", |
@@ -86,7 +86,7 @@ class ConfigParameters(object): | |||
86 | action['msg'] = "Only one target can be used with the --environment option." | 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: | 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." | 88 | action['msg'] = "No target should be used with the --environment and --buildfile options." |
89 | elif len(self.options.pkgs_to_build) > 0: | 89 | elif self.options.pkgs_to_build: |
90 | action['action'] = ["showEnvironmentTarget", self.options.pkgs_to_build] | 90 | action['action'] = ["showEnvironmentTarget", self.options.pkgs_to_build] |
91 | else: | 91 | else: |
92 | action['action'] = ["showEnvironment", self.options.buildfile] | 92 | action['action'] = ["showEnvironment", self.options.buildfile] |
@@ -124,7 +124,7 @@ class CookerConfiguration(object): | |||
124 | self.prefile = [] | 124 | self.prefile = [] |
125 | self.postfile = [] | 125 | self.postfile = [] |
126 | self.cmd = None | 126 | self.cmd = None |
127 | self.abort = True | 127 | self.halt = True |
128 | self.force = False | 128 | self.force = False |
129 | self.profile = False | 129 | self.profile = False |
130 | self.nosetscene = False | 130 | self.nosetscene = False |
@@ -160,12 +160,7 @@ def catch_parse_error(func): | |||
160 | def wrapped(fn, *args): | 160 | def wrapped(fn, *args): |
161 | try: | 161 | try: |
162 | return func(fn, *args) | 162 | return func(fn, *args) |
163 | except IOError as exc: | 163 | except Exception as exc: |
164 | import traceback | ||
165 | parselog.critical(traceback.format_exc()) | ||
166 | parselog.critical("Unable to parse %s: %s" % (fn, exc)) | ||
167 | raise bb.BBHandledException() | ||
168 | except bb.data_smart.ExpansionError as exc: | ||
169 | import traceback | 164 | import traceback |
170 | 165 | ||
171 | bbdir = os.path.dirname(__file__) + os.sep | 166 | bbdir = os.path.dirname(__file__) + os.sep |
@@ -177,14 +172,11 @@ def catch_parse_error(func): | |||
177 | break | 172 | break |
178 | parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb)) | 173 | parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb)) |
179 | raise bb.BBHandledException() | 174 | raise bb.BBHandledException() |
180 | except bb.parse.ParseError as exc: | ||
181 | parselog.critical(str(exc)) | ||
182 | raise bb.BBHandledException() | ||
183 | return wrapped | 175 | return wrapped |
184 | 176 | ||
185 | @catch_parse_error | 177 | @catch_parse_error |
186 | def parse_config_file(fn, data, include=True): | 178 | def parse_config_file(fn, data, include=True): |
187 | return bb.parse.handle(fn, data, include) | 179 | return bb.parse.handle(fn, data, include, baseconfig=True) |
188 | 180 | ||
189 | @catch_parse_error | 181 | @catch_parse_error |
190 | def _inherit(bbclass, data): | 182 | def _inherit(bbclass, data): |
@@ -210,7 +202,7 @@ def findConfigFile(configfile, data): | |||
210 | 202 | ||
211 | # | 203 | # |
212 | # We search for a conf/bblayers.conf under an entry in BBPATH or in cwd working | 204 | # 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. | 205 | # up to /. If that fails, bitbake would fall back to cwd. |
214 | # | 206 | # |
215 | 207 | ||
216 | def findTopdir(): | 208 | def findTopdir(): |
@@ -223,11 +215,8 @@ def findTopdir(): | |||
223 | layerconf = findConfigFile("bblayers.conf", d) | 215 | layerconf = findConfigFile("bblayers.conf", d) |
224 | if layerconf: | 216 | if layerconf: |
225 | return os.path.dirname(os.path.dirname(layerconf)) | 217 | return os.path.dirname(os.path.dirname(layerconf)) |
226 | if bbpath: | 218 | |
227 | bitbakeconf = bb.utils.which(bbpath, "conf/bitbake.conf") | 219 | return os.path.abspath(os.getcwd()) |
228 | if bitbakeconf: | ||
229 | return os.path.dirname(os.path.dirname(bitbakeconf)) | ||
230 | return None | ||
231 | 220 | ||
232 | class CookerDataBuilder(object): | 221 | class CookerDataBuilder(object): |
233 | 222 | ||
@@ -250,10 +239,14 @@ class CookerDataBuilder(object): | |||
250 | self.savedenv = bb.data.init() | 239 | self.savedenv = bb.data.init() |
251 | for k in cookercfg.env: | 240 | for k in cookercfg.env: |
252 | self.savedenv.setVar(k, cookercfg.env[k]) | 241 | self.savedenv.setVar(k, cookercfg.env[k]) |
242 | if k in bb.data_smart.bitbake_renamed_vars: | ||
243 | bb.error('Shell environment variable %s has been renamed to %s' % (k, bb.data_smart.bitbake_renamed_vars[k])) | ||
244 | bb.fatal("Exiting to allow enviroment variables to be corrected") | ||
253 | 245 | ||
254 | filtered_keys = bb.utils.approved_variables() | 246 | filtered_keys = bb.utils.approved_variables() |
255 | bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys) | 247 | bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys) |
256 | self.basedata.setVar("BB_ORIGENV", self.savedenv) | 248 | self.basedata.setVar("BB_ORIGENV", self.savedenv) |
249 | self.basedata.setVar("__bbclasstype", "global") | ||
257 | 250 | ||
258 | if worker: | 251 | if worker: |
259 | self.basedata.setVar("BB_WORKERCONTEXT", "1") | 252 | self.basedata.setVar("BB_WORKERCONTEXT", "1") |
@@ -261,15 +254,15 @@ class CookerDataBuilder(object): | |||
261 | self.data = self.basedata | 254 | self.data = self.basedata |
262 | self.mcdata = {} | 255 | self.mcdata = {} |
263 | 256 | ||
264 | def parseBaseConfiguration(self): | 257 | def parseBaseConfiguration(self, worker=False): |
258 | mcdata = {} | ||
265 | data_hash = hashlib.sha256() | 259 | data_hash = hashlib.sha256() |
266 | try: | 260 | try: |
267 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) | 261 | self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles) |
268 | 262 | ||
269 | if self.data.getVar("BB_WORKERCONTEXT", False) is None: | 263 | if self.data.getVar("BB_WORKERCONTEXT", False) is None and not worker: |
270 | bb.fetch.fetcher_init(self.data) | 264 | bb.fetch.fetcher_init(self.data) |
271 | bb.parse.init_parser(self.data) | 265 | bb.parse.init_parser(self.data) |
272 | bb.codeparser.parser_cache_init(self.data) | ||
273 | 266 | ||
274 | bb.event.fire(bb.event.ConfigParsed(), self.data) | 267 | bb.event.fire(bb.event.ConfigParsed(), self.data) |
275 | 268 | ||
@@ -287,38 +280,62 @@ class CookerDataBuilder(object): | |||
287 | 280 | ||
288 | bb.parse.init_parser(self.data) | 281 | bb.parse.init_parser(self.data) |
289 | data_hash.update(self.data.get_hash().encode('utf-8')) | 282 | data_hash.update(self.data.get_hash().encode('utf-8')) |
290 | self.mcdata[''] = self.data | 283 | mcdata[''] = self.data |
291 | 284 | ||
292 | multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split() | 285 | multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split() |
293 | for config in multiconfig: | 286 | for config in multiconfig: |
294 | mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config) | 287 | if config[0].isdigit(): |
295 | bb.event.fire(bb.event.ConfigParsed(), mcdata) | 288 | bb.fatal("Multiconfig name '%s' is invalid as multiconfigs cannot start with a digit" % config) |
296 | self.mcdata[config] = mcdata | 289 | parsed_mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config) |
297 | data_hash.update(mcdata.get_hash().encode('utf-8')) | 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')) | ||
298 | if multiconfig: | 293 | if multiconfig: |
299 | bb.event.fire(bb.event.MultiConfigParsed(self.mcdata), self.data) | 294 | bb.event.fire(bb.event.MultiConfigParsed(mcdata), self.data) |
300 | 295 | ||
301 | self.data_hash = data_hash.hexdigest() | 296 | self.data_hash = data_hash.hexdigest() |
302 | except (SyntaxError, bb.BBHandledException): | ||
303 | raise bb.BBHandledException() | ||
304 | except bb.data_smart.ExpansionError as e: | 297 | except bb.data_smart.ExpansionError as e: |
305 | logger.error(str(e)) | 298 | logger.error(str(e)) |
306 | raise bb.BBHandledException() | 299 | raise bb.BBHandledException() |
307 | except Exception: | 300 | |
308 | logger.exception("Error parsing configuration files") | 301 | bb.codeparser.update_module_dependencies(self.data) |
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: | ||
309 | raise bb.BBHandledException() | 320 | raise bb.BBHandledException() |
310 | 321 | ||
322 | for mc in mcdata: | ||
323 | mcdata[mc].renameVar("__depends", "__base_depends") | ||
324 | mcdata[mc].setVar("__bbclasstype", "recipe") | ||
325 | |||
311 | # Create a copy so we can reset at a later date when UIs disconnect | 326 | # Create a copy so we can reset at a later date when UIs disconnect |
312 | self.origdata = self.data | 327 | self.mcorigdata = mcdata |
313 | self.data = bb.data.createCopy(self.origdata) | 328 | for mc in mcdata: |
314 | self.mcdata[''] = self.data | 329 | self.mcdata[mc] = bb.data.createCopy(mcdata[mc]) |
330 | self.data = self.mcdata[''] | ||
315 | 331 | ||
316 | def reset(self): | 332 | def reset(self): |
317 | # We may not have run parseBaseConfiguration() yet | 333 | # We may not have run parseBaseConfiguration() yet |
318 | if not hasattr(self, 'origdata'): | 334 | if not hasattr(self, 'mcorigdata'): |
319 | return | 335 | return |
320 | self.data = bb.data.createCopy(self.origdata) | 336 | for mc in self.mcorigdata: |
321 | self.mcdata[''] = self.data | 337 | self.mcdata[mc] = bb.data.createCopy(self.mcorigdata[mc]) |
338 | self.data = self.mcdata[''] | ||
322 | 339 | ||
323 | def _findLayerConf(self, data): | 340 | def _findLayerConf(self, data): |
324 | return findConfigFile("bblayers.conf", data) | 341 | return findConfigFile("bblayers.conf", data) |
@@ -333,15 +350,23 @@ class CookerDataBuilder(object): | |||
333 | 350 | ||
334 | layerconf = self._findLayerConf(data) | 351 | layerconf = self._findLayerConf(data) |
335 | if layerconf: | 352 | if layerconf: |
336 | parselog.debug(2, "Found bblayers.conf (%s)", layerconf) | 353 | parselog.debug2("Found bblayers.conf (%s)", layerconf) |
337 | # By definition bblayers.conf is in conf/ of TOPDIR. | 354 | # By definition bblayers.conf is in conf/ of TOPDIR. |
338 | # We may have been called with cwd somewhere else so reset TOPDIR | 355 | # We may have been called with cwd somewhere else so reset TOPDIR |
339 | data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf))) | 356 | data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf))) |
340 | data = parse_config_file(layerconf, data) | 357 | data = parse_config_file(layerconf, data) |
341 | 358 | ||
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 | |||
342 | layers = (data.getVar('BBLAYERS') or "").split() | 364 | layers = (data.getVar('BBLAYERS') or "").split() |
343 | broken_layers = [] | 365 | broken_layers = [] |
344 | 366 | ||
367 | if not layers: | ||
368 | bb.fatal("The bblayers.conf file doesn't contain any BBLAYERS definition") | ||
369 | |||
345 | data = bb.data.createCopy(data) | 370 | data = bb.data.createCopy(data) |
346 | approved = bb.utils.approved_variables() | 371 | approved = bb.utils.approved_variables() |
347 | 372 | ||
@@ -357,8 +382,10 @@ class CookerDataBuilder(object): | |||
357 | parselog.critical("Please check BBLAYERS in %s" % (layerconf)) | 382 | parselog.critical("Please check BBLAYERS in %s" % (layerconf)) |
358 | raise bb.BBHandledException() | 383 | raise bb.BBHandledException() |
359 | 384 | ||
385 | layerseries = None | ||
386 | compat_entries = {} | ||
360 | for layer in layers: | 387 | for layer in layers: |
361 | parselog.debug(2, "Adding layer %s", layer) | 388 | parselog.debug2("Adding layer %s", layer) |
362 | if 'HOME' in approved and '~' in layer: | 389 | if 'HOME' in approved and '~' in layer: |
363 | layer = os.path.expanduser(layer) | 390 | layer = os.path.expanduser(layer) |
364 | if layer.endswith('/'): | 391 | if layer.endswith('/'): |
@@ -369,8 +396,27 @@ class CookerDataBuilder(object): | |||
369 | data.expandVarref('LAYERDIR') | 396 | data.expandVarref('LAYERDIR') |
370 | data.expandVarref('LAYERDIR_RE') | 397 | data.expandVarref('LAYERDIR_RE') |
371 | 398 | ||
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 | |||
372 | data.delVar('LAYERDIR_RE') | 416 | data.delVar('LAYERDIR_RE') |
373 | data.delVar('LAYERDIR') | 417 | data.delVar('LAYERDIR') |
418 | for c in compat_entries: | ||
419 | data.setVar("LAYERSERIES_COMPAT_%s" % c, " ".join(sorted(compat_entries[c]))) | ||
374 | 420 | ||
375 | bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split() | 421 | bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split() |
376 | collections = (data.getVar('BBFILE_COLLECTIONS') or "").split() | 422 | collections = (data.getVar('BBFILE_COLLECTIONS') or "").split() |
@@ -389,26 +435,38 @@ class CookerDataBuilder(object): | |||
389 | if invalid: | 435 | if invalid: |
390 | bb.fatal("BBFILES_DYNAMIC entries must be of the form {!}<collection name>:<filename pattern>, not:\n %s" % "\n ".join(invalid)) | 436 | bb.fatal("BBFILES_DYNAMIC entries must be of the form {!}<collection name>:<filename pattern>, not:\n %s" % "\n ".join(invalid)) |
391 | 437 | ||
392 | layerseries = set((data.getVar("LAYERSERIES_CORENAMES") or "").split()) | ||
393 | collections_tmp = collections[:] | 438 | collections_tmp = collections[:] |
394 | for c in collections: | 439 | for c in collections: |
395 | collections_tmp.remove(c) | 440 | collections_tmp.remove(c) |
396 | if c in collections_tmp: | 441 | if c in collections_tmp: |
397 | bb.fatal("Found duplicated BBFILE_COLLECTIONS '%s', check bblayers.conf or layer.conf to fix it." % c) | 442 | bb.fatal("Found duplicated BBFILE_COLLECTIONS '%s', check bblayers.conf or layer.conf to fix it." % c) |
398 | compat = set((data.getVar("LAYERSERIES_COMPAT_%s" % c) or "").split()) | 443 | |
444 | compat = set() | ||
445 | if c in compat_entries: | ||
446 | compat = compat_entries[c] | ||
447 | if compat and not layerseries: | ||
448 | bb.fatal("No core layer found to work with layer '%s'. Missing entry in bblayers.conf?" % c) | ||
399 | if compat and not (compat & layerseries): | 449 | 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)" | 450 | 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))) | 451 | % (c, " ".join(layerseries), " ".join(compat))) |
402 | elif not compat and not data.getVar("BB_WORKERCONTEXT"): | 452 | 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)) | 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)) |
404 | 454 | ||
455 | data.setVar("LAYERSERIES_CORENAMES", " ".join(sorted(layerseries))) | ||
456 | |||
405 | if not data.getVar("BBPATH"): | 457 | if not data.getVar("BBPATH"): |
406 | msg = "The BBPATH variable is not set" | 458 | msg = "The BBPATH variable is not set" |
407 | if not layerconf: | 459 | if not layerconf: |
408 | msg += (" and bitbake did not find a conf/bblayers.conf file in" | 460 | msg += (" and bitbake did not find a conf/bblayers.conf file in" |
409 | " the expected location.\nMaybe you accidentally" | 461 | " the expected location.\nMaybe you accidentally" |
410 | " invoked bitbake from the wrong directory?") | 462 | " invoked bitbake from the wrong directory?") |
411 | raise SystemExit(msg) | 463 | bb.fatal(msg) |
464 | |||
465 | if not data.getVar("TOPDIR"): | ||
466 | data.setVar("TOPDIR", os.path.abspath(os.getcwd())) | ||
467 | if not data.getVar("BB_CACHEDIR"): | ||
468 | data.setVar("BB_CACHEDIR", "${TOPDIR}/cache") | ||
469 | bb.codeparser.parser_cache_init(data.getVar("BB_CACHEDIR")) | ||
412 | 470 | ||
413 | data = parse_config_file(os.path.join("conf", "bitbake.conf"), data) | 471 | data = parse_config_file(os.path.join("conf", "bitbake.conf"), data) |
414 | 472 | ||
@@ -421,7 +479,7 @@ class CookerDataBuilder(object): | |||
421 | for bbclass in bbclasses: | 479 | for bbclass in bbclasses: |
422 | data = _inherit(bbclass, data) | 480 | data = _inherit(bbclass, data) |
423 | 481 | ||
424 | # Nomally we only register event handlers at the end of parsing .bb files | 482 | # Normally we only register event handlers at the end of parsing .bb files |
425 | # We register any handlers we've found so far here... | 483 | # We register any handlers we've found so far here... |
426 | for var in data.getVar('__BBHANDLERS', False) or []: | 484 | for var in data.getVar('__BBHANDLERS', False) or []: |
427 | handlerfn = data.getVarFlag(var, "filename", False) | 485 | handlerfn = data.getVarFlag(var, "filename", False) |
@@ -435,3 +493,54 @@ class CookerDataBuilder(object): | |||
435 | 493 | ||
436 | return data | 494 | return data |
437 | 495 | ||
496 | @staticmethod | ||
497 | def _parse_recipe(bb_data, bbfile, appends, mc, layername): | ||
498 | bb_data.setVar("__BBMULTICONFIG", mc) | ||
499 | bb_data.setVar("FILE_LAYERNAME", layername) | ||
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)) | ||
506 | |||
507 | return bb.parse.handle(bbfile, bb_data) | ||
508 | |||
509 | def parseRecipeVariants(self, bbfile, appends, virtonly=False, mc=None, layername=None): | ||
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") | ||
519 | return self._parse_recipe(bb_data, bbfile, appends, mc, layername) | ||
520 | |||
521 | if mc is not None: | ||
522 | bb_data = self.mcdata[mc].createCopy() | ||
523 | return self._parse_recipe(bb_data, bbfile, appends, mc, layername) | ||
524 | |||
525 | bb_data = self.data.createCopy() | ||
526 | datastores = self._parse_recipe(bb_data, bbfile, appends, '', layername) | ||
527 | |||
528 | for mc in self.mcdata: | ||
529 | if not mc: | ||
530 | continue | ||
531 | bb_data = self.mcdata[mc].createCopy() | ||
532 | newstores = self._parse_recipe(bb_data, bbfile, appends, mc, layername) | ||
533 | for ns in newstores: | ||
534 | datastores["mc:%s:%s" % (mc, ns)] = newstores[ns] | ||
535 | |||
536 | return datastores | ||
537 | |||
538 | def parseRecipe(self, virtualfn, appends, layername): | ||
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) | ||
545 | datastores = self.parseRecipeVariants(virtualfn, appends, virtonly=True, layername=layername) | ||
546 | return datastores[virtual] | ||