diff options
Diffstat (limited to 'mesonbuild/cmake/traceparser.py')
-rw-r--r-- | mesonbuild/cmake/traceparser.py | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/mesonbuild/cmake/traceparser.py b/mesonbuild/cmake/traceparser.py index 4aa34f1..7b29c86 100644 --- a/mesonbuild/cmake/traceparser.py +++ b/mesonbuild/cmake/traceparser.py @@ -24,6 +24,7 @@ import typing as T from pathlib import Path import re import os +import json class CMakeTraceLine: def __init__(self, file, line, func, args): @@ -80,11 +81,12 @@ class CMakeTraceParser: self.cmake_version = cmake_version # type: str self.trace_file = 'cmake_trace.txt' self.trace_file_path = Path(build_dir) / self.trace_file - self.trace_format = 'human' + self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human' def trace_args(self) -> T.List[str]: arg_map = { 'human': ['--trace', '--trace-expand'], + 'json-v1': ['--trace-expand', '--trace-format=json-v1'], } base_args = ['--no-warn-unused-cli'] @@ -109,8 +111,10 @@ class CMakeTraceParser: lexer1 = None if self.trace_format == 'human': lexer1 = self._lex_trace_human(trace) + elif self.trace_format == 'json-v1': + lexer1 = self._lex_trace_json(trace) else: - raise CMakeException('CMake: Internal error: Invalid trace format {}. Expected [human]'.format(self.trace_format)) + raise CMakeException('CMake: Internal error: Invalid trace format {}. Expected [human, json-v1]'.format(self.trace_format)) # All supported functions functions = { @@ -421,21 +425,27 @@ class CMakeTraceParser: # Neither of these is awesome for obvious reasons. I'm going to try # option 1 first and fall back to 2, as 1 requires less code and less # synchroniztion for cmake changes. + # + # With the JSON output format, introduced in CMake 3.17, spaces are + # handled properly and we don't have to do either options arglist = [] # type: T.List[T.Tuple[str, T.List[str]]] - name = args.pop(0) - values = [] - prop_regex = re.compile(r'^[A-Z_]+$') - for a in args: - if prop_regex.match(a): - if values: - arglist.append((name, ' '.join(values).split(';'))) - name = a - values = [] - else: - values.append(a) - if values: - arglist.append((name, ' '.join(values).split(';'))) + if self.trace_format == 'human': + name = args.pop(0) + values = [] + prop_regex = re.compile(r'^[A-Z_]+$') + for a in args: + if prop_regex.match(a): + if values: + arglist.append((name, ' '.join(values).split(';'))) + name = a + values = [] + else: + values.append(a) + if values: + arglist.append((name, ' '.join(values).split(';'))) + else: + arglist = [(x[0], x[1].split(';')) for x in zip(args[::2], args[1::2])] for name, value in arglist: for i in targets: @@ -549,7 +559,20 @@ class CMakeTraceParser: yield CMakeTraceLine(file, line, func, args) + def _lex_trace_json(self, trace: str): + lines = trace.splitlines(keepends=False) + lines.pop(0) # The first line is the version + for i in lines: + data = json.loads(i) + args = data['args'] + args = [parse_generator_expressions(x) for x in args] + yield CMakeTraceLine(data['file'], data['line'], data['cmd'], args) + def _guess_files(self, broken_list: T.List[str]) -> T.List[str]: + # Nothing has to be done for newer formats + if self.trace_format != 'human': + return broken_list + # Try joining file paths that contain spaces reg_start = re.compile(r'^([A-Za-z]:)?/.*/[^./]+$') |