diff options
Diffstat (limited to 'bitbake/lib/bb/cooker.py')
-rw-r--r-- | bitbake/lib/bb/cooker.py | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 6318ef4a8f..6fce19b464 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
@@ -17,7 +17,7 @@ import threading | |||
17 | from io import StringIO, UnsupportedOperation | 17 | from io import StringIO, UnsupportedOperation |
18 | from contextlib import closing | 18 | from contextlib import closing |
19 | from collections import defaultdict, namedtuple | 19 | from collections import defaultdict, namedtuple |
20 | import bb, bb.exceptions, bb.command | 20 | import bb, bb.command |
21 | from bb import utils, data, parse, event, cache, providers, taskdata, runqueue, build | 21 | from bb import utils, data, parse, event, cache, providers, taskdata, runqueue, build |
22 | import queue | 22 | import queue |
23 | import signal | 23 | import signal |
@@ -134,7 +134,8 @@ class BBCooker: | |||
134 | self.baseconfig_valid = False | 134 | self.baseconfig_valid = False |
135 | self.parsecache_valid = False | 135 | self.parsecache_valid = False |
136 | self.eventlog = None | 136 | self.eventlog = None |
137 | self.skiplist = {} | 137 | # The skiplists, one per multiconfig |
138 | self.skiplist_by_mc = defaultdict(dict) | ||
138 | self.featureset = CookerFeatures() | 139 | self.featureset = CookerFeatures() |
139 | if featureSet: | 140 | if featureSet: |
140 | for f in featureSet: | 141 | for f in featureSet: |
@@ -612,8 +613,8 @@ class BBCooker: | |||
612 | localdata = {} | 613 | localdata = {} |
613 | 614 | ||
614 | for mc in self.multiconfigs: | 615 | for mc in self.multiconfigs: |
615 | taskdata[mc] = bb.taskdata.TaskData(halt, skiplist=self.skiplist, allowincomplete=allowincomplete) | 616 | taskdata[mc] = bb.taskdata.TaskData(halt, skiplist=self.skiplist_by_mc[mc], allowincomplete=allowincomplete) |
616 | localdata[mc] = data.createCopy(self.databuilder.mcdata[mc]) | 617 | localdata[mc] = bb.data.createCopy(self.databuilder.mcdata[mc]) |
617 | bb.data.expandKeys(localdata[mc]) | 618 | bb.data.expandKeys(localdata[mc]) |
618 | 619 | ||
619 | current = 0 | 620 | current = 0 |
@@ -933,7 +934,7 @@ class BBCooker: | |||
933 | for mc in self.multiconfigs: | 934 | for mc in self.multiconfigs: |
934 | # First get list of recipes, including skipped | 935 | # First get list of recipes, including skipped |
935 | recipefns = list(self.recipecaches[mc].pkg_fn.keys()) | 936 | recipefns = list(self.recipecaches[mc].pkg_fn.keys()) |
936 | recipefns.extend(self.skiplist.keys()) | 937 | recipefns.extend(self.skiplist_by_mc[mc].keys()) |
937 | 938 | ||
938 | # Work out list of bbappends that have been applied | 939 | # Work out list of bbappends that have been applied |
939 | applied_appends = [] | 940 | applied_appends = [] |
@@ -2097,7 +2098,6 @@ class Parser(multiprocessing.Process): | |||
2097 | except Exception as exc: | 2098 | except Exception as exc: |
2098 | tb = sys.exc_info()[2] | 2099 | tb = sys.exc_info()[2] |
2099 | exc.recipe = filename | 2100 | exc.recipe = filename |
2100 | exc.traceback = list(bb.exceptions.extract_traceback(tb, context=3)) | ||
2101 | return True, None, exc | 2101 | return True, None, exc |
2102 | # Need to turn BaseExceptions into Exceptions here so we gracefully shutdown | 2102 | # Need to turn BaseExceptions into Exceptions here so we gracefully shutdown |
2103 | # and for example a worker thread doesn't just exit on its own in response to | 2103 | # and for example a worker thread doesn't just exit on its own in response to |
@@ -2298,8 +2298,12 @@ class CookerParser(object): | |||
2298 | return False | 2298 | return False |
2299 | except ParsingFailure as exc: | 2299 | except ParsingFailure as exc: |
2300 | self.error += 1 | 2300 | self.error += 1 |
2301 | logger.error('Unable to parse %s: %s' % | 2301 | |
2302 | (exc.recipe, bb.exceptions.to_string(exc.realexception))) | 2302 | exc_desc = str(exc) |
2303 | if isinstance(exc, SystemExit) and not isinstance(exc.code, str): | ||
2304 | exc_desc = 'Exited with "%d"' % exc.code | ||
2305 | |||
2306 | logger.error('Unable to parse %s: %s' % (exc.recipe, exc_desc)) | ||
2303 | self.shutdown(clean=False) | 2307 | self.shutdown(clean=False) |
2304 | return False | 2308 | return False |
2305 | except bb.parse.ParseError as exc: | 2309 | except bb.parse.ParseError as exc: |
@@ -2308,20 +2312,33 @@ class CookerParser(object): | |||
2308 | self.shutdown(clean=False, eventmsg=str(exc)) | 2312 | self.shutdown(clean=False, eventmsg=str(exc)) |
2309 | return False | 2313 | return False |
2310 | except bb.data_smart.ExpansionError as exc: | 2314 | except bb.data_smart.ExpansionError as exc: |
2315 | def skip_frames(f, fn_prefix): | ||
2316 | while f and f.tb_frame.f_code.co_filename.startswith(fn_prefix): | ||
2317 | f = f.tb_next | ||
2318 | return f | ||
2319 | |||
2311 | self.error += 1 | 2320 | self.error += 1 |
2312 | bbdir = os.path.dirname(__file__) + os.sep | 2321 | bbdir = os.path.dirname(__file__) + os.sep |
2313 | etype, value, _ = sys.exc_info() | 2322 | etype, value, tb = sys.exc_info() |
2314 | tb = list(itertools.dropwhile(lambda e: e.filename.startswith(bbdir), exc.traceback)) | 2323 | |
2324 | # Remove any frames where the code comes from bitbake. This | ||
2325 | # prevents deep (and pretty useless) backtraces for expansion error | ||
2326 | tb = skip_frames(tb, bbdir) | ||
2327 | cur = tb | ||
2328 | while cur: | ||
2329 | cur.tb_next = skip_frames(cur.tb_next, bbdir) | ||
2330 | cur = cur.tb_next | ||
2331 | |||
2315 | logger.error('ExpansionError during parsing %s', value.recipe, | 2332 | logger.error('ExpansionError during parsing %s', value.recipe, |
2316 | exc_info=(etype, value, tb)) | 2333 | exc_info=(etype, value, tb)) |
2317 | self.shutdown(clean=False) | 2334 | self.shutdown(clean=False) |
2318 | return False | 2335 | return False |
2319 | except Exception as exc: | 2336 | except Exception as exc: |
2320 | self.error += 1 | 2337 | self.error += 1 |
2321 | etype, value, tb = sys.exc_info() | 2338 | _, value, _ = sys.exc_info() |
2322 | if hasattr(value, "recipe"): | 2339 | if hasattr(value, "recipe"): |
2323 | logger.error('Unable to parse %s' % value.recipe, | 2340 | logger.error('Unable to parse %s' % value.recipe, |
2324 | exc_info=(etype, value, exc.traceback)) | 2341 | exc_info=sys.exc_info()) |
2325 | else: | 2342 | else: |
2326 | # Most likely, an exception occurred during raising an exception | 2343 | # Most likely, an exception occurred during raising an exception |
2327 | import traceback | 2344 | import traceback |
@@ -2342,7 +2359,7 @@ class CookerParser(object): | |||
2342 | for virtualfn, info_array in result: | 2359 | for virtualfn, info_array in result: |
2343 | if info_array[0].skipped: | 2360 | if info_array[0].skipped: |
2344 | self.skipped += 1 | 2361 | self.skipped += 1 |
2345 | self.cooker.skiplist[virtualfn] = SkippedPackage(info_array[0]) | 2362 | self.cooker.skiplist_by_mc[mc][virtualfn] = SkippedPackage(info_array[0]) |
2346 | self.bb_caches[mc].add_info(virtualfn, info_array, self.cooker.recipecaches[mc], | 2363 | self.bb_caches[mc].add_info(virtualfn, info_array, self.cooker.recipecaches[mc], |
2347 | parsed=parsed, watcher = self.cooker.add_filewatch) | 2364 | parsed=parsed, watcher = self.cooker.add_filewatch) |
2348 | return True | 2365 | return True |