|
|
|
@ -27,6 +27,9 @@ import re |
|
|
|
|
import json |
|
|
|
|
import textwrap |
|
|
|
|
|
|
|
|
|
if T.TYPE_CHECKING: |
|
|
|
|
from ..environment import Environment |
|
|
|
|
|
|
|
|
|
class CMakeTraceLine: |
|
|
|
|
def __init__(self, file_str: str, line: int, func: str, args: T.List[str]) -> None: |
|
|
|
|
self.file = CMakeTraceLine._to_path(file_str) |
|
|
|
@ -90,7 +93,7 @@ class CMakeGeneratorTarget(CMakeTarget): |
|
|
|
|
self.working_dir = None # type: T.Optional[Path] |
|
|
|
|
|
|
|
|
|
class CMakeTraceParser: |
|
|
|
|
def __init__(self, cmake_version: str, build_dir: Path, permissive: bool = True) -> None: |
|
|
|
|
def __init__(self, cmake_version: str, build_dir: Path, env: 'Environment', permissive: bool = True) -> None: |
|
|
|
|
self.vars: T.Dict[str, T.List[str]] = {} |
|
|
|
|
self.vars_by_file: T.Dict[Path, T.Dict[str, T.List[str]]] = {} |
|
|
|
|
self.targets: T.Dict[str, CMakeTarget] = {} |
|
|
|
@ -101,6 +104,7 @@ class CMakeTraceParser: |
|
|
|
|
# T.List of targes that were added with add_custom_command to generate files |
|
|
|
|
self.custom_targets = [] # type: T.List[CMakeGeneratorTarget] |
|
|
|
|
|
|
|
|
|
self.env = env |
|
|
|
|
self.permissive = permissive # type: bool |
|
|
|
|
self.cmake_version = cmake_version # type: str |
|
|
|
|
self.trace_file = 'cmake_trace.txt' |
|
|
|
@ -194,6 +198,38 @@ class CMakeTraceParser: |
|
|
|
|
if fn: |
|
|
|
|
fn(l) |
|
|
|
|
|
|
|
|
|
# Evaluate generator expressions |
|
|
|
|
strlist_gen: T.Callable[[T.List[str]], T.List[str]] = lambda strlist: [parse_generator_expressions(x, self) for x in strlist] |
|
|
|
|
pathlist_gen: T.Callable[[T.List[Path]], T.List[Path]] = lambda plist: [Path(parse_generator_expressions(str(x), self)) for x in plist] |
|
|
|
|
|
|
|
|
|
self.vars = {k: strlist_gen(v) for k, v in self.vars.items()} |
|
|
|
|
self.vars_by_file = { |
|
|
|
|
p: {k: strlist_gen(v) for k, v in d.items()} |
|
|
|
|
for p, d in self.vars_by_file.items() |
|
|
|
|
} |
|
|
|
|
self.explicit_headers = set(Path(parse_generator_expressions(str(x), self)) for x in self.explicit_headers) |
|
|
|
|
self.cache = { |
|
|
|
|
k: CMakeCacheEntry( |
|
|
|
|
strlist_gen(v.value), |
|
|
|
|
v.type |
|
|
|
|
) |
|
|
|
|
for k, v in self.cache.items() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for tgt in self.targets.values(): |
|
|
|
|
tgtlist_gen: T.Callable[[T.List[str], CMakeTarget], T.List[str]] = lambda strlist, t: [parse_generator_expressions(x, self, context_tgt=t) for x in strlist] |
|
|
|
|
tgt.name = parse_generator_expressions(tgt.name, self, context_tgt=tgt) |
|
|
|
|
tgt.type = parse_generator_expressions(tgt.type, self, context_tgt=tgt) |
|
|
|
|
tgt.properties = { |
|
|
|
|
k: tgtlist_gen(v, tgt) for k, v in tgt.properties.items() |
|
|
|
|
} if tgt.properties is not None else None |
|
|
|
|
tgt.depends = tgtlist_gen(tgt.depends, tgt) |
|
|
|
|
|
|
|
|
|
for ctgt in self.custom_targets: |
|
|
|
|
ctgt.outputs = pathlist_gen(ctgt.outputs) |
|
|
|
|
ctgt.command = [strlist_gen(x) for x in ctgt.command] |
|
|
|
|
ctgt.working_dir = Path(parse_generator_expressions(str(ctgt.working_dir), self)) if ctgt.working_dir is not None else None |
|
|
|
|
|
|
|
|
|
# Postprocess |
|
|
|
|
for tgt in self.targets.values(): |
|
|
|
|
tgt.strip_properties() |
|
|
|
@ -688,7 +724,6 @@ class CMakeTraceParser: |
|
|
|
|
line = mo_file_line.group(3) |
|
|
|
|
func = mo_file_line.group(4) |
|
|
|
|
args = mo_file_line.group(5) |
|
|
|
|
args = parse_generator_expressions(args) |
|
|
|
|
argl = args.split(' ') |
|
|
|
|
argl = list(map(lambda x: x.strip(), argl)) |
|
|
|
|
|
|
|
|
@ -706,7 +741,6 @@ class CMakeTraceParser: |
|
|
|
|
args = data['args'] |
|
|
|
|
for j in args: |
|
|
|
|
assert isinstance(j, str) |
|
|
|
|
args = [parse_generator_expressions(x) for x in args] |
|
|
|
|
yield CMakeTraceLine(data['file'], data['line'], data['cmd'], args) |
|
|
|
|
|
|
|
|
|
def _flatten_args(self, args: T.List[str]) -> T.List[str]: |
|
|
|
|