| # SPDX-License-Identifer: Apache-2.0 |
| # Copyright 2021 The Meson development team |
| from __future__ import annotations |
| |
| from .common import cmake_is_debug |
| from .. import mlog |
| |
| from pathlib import Path |
| import re |
| import typing as T |
| |
| if T.TYPE_CHECKING: |
| from .traceparser import CMakeTraceParser |
| from ..environment import Environment |
| from ..compilers import Compiler |
| from ..dependencies import MissingCompiler |
| |
| class ResolvedTarget: |
| def __init__(self) -> None: |
| self.include_directories: T.List[str] = [] |
| self.link_flags: T.List[str] = [] |
| self.public_compile_opts: T.List[str] = [] |
| self.libraries: T.List[str] = [] |
| |
| def resolve_cmake_trace_targets(target_name: str, |
| trace: 'CMakeTraceParser', |
| env: 'Environment', |
| *, |
| clib_compiler: T.Union['MissingCompiler', 'Compiler'] = None, |
| not_found_warning: T.Callable[[str], None] = lambda x: None) -> ResolvedTarget: |
| res = ResolvedTarget() |
| targets = [target_name] |
| |
| # recognise arguments we should pass directly to the linker |
| reg_is_lib = re.compile(r'^(-l[a-zA-Z0-9_]+|-l?pthread)$') |
| reg_is_maybe_bare_lib = re.compile(r'^[a-zA-Z0-9_]+$') |
| |
| is_debug = cmake_is_debug(env) |
| |
| processed_targets: T.List[str] = [] |
| while len(targets) > 0: |
| curr = targets.pop(0) |
| |
| # Skip already processed targets |
| if curr in processed_targets: |
| continue |
| |
| if curr not in trace.targets: |
| if reg_is_lib.match(curr): |
| res.libraries += [curr] |
| elif Path(curr).is_absolute() and Path(curr).exists(): |
| res.libraries += [curr] |
| elif reg_is_maybe_bare_lib.match(curr) and clib_compiler: |
| # CMake library dependencies can be passed as bare library names, |
| # CMake brute-forces a combination of prefix/suffix combinations to find the |
| # right library. Assume any bare argument passed which is not also a CMake |
| # target must be a system library we should try to link against. |
| res.libraries += clib_compiler.find_library(curr, env, []) |
| else: |
| not_found_warning(curr) |
| continue |
| |
| tgt = trace.targets[curr] |
| cfgs = [] |
| cfg = '' |
| mlog.debug(tgt) |
| |
| if 'INTERFACE_INCLUDE_DIRECTORIES' in tgt.properties: |
| res.include_directories += [x for x in tgt.properties['INTERFACE_INCLUDE_DIRECTORIES'] if x] |
| |
| if 'INTERFACE_LINK_OPTIONS' in tgt.properties: |
| res.link_flags += [x for x in tgt.properties['INTERFACE_LINK_OPTIONS'] if x] |
| |
| if 'INTERFACE_COMPILE_DEFINITIONS' in tgt.properties: |
| res.public_compile_opts += ['-D' + re.sub('^-D', '', x) for x in tgt.properties['INTERFACE_COMPILE_DEFINITIONS'] if x] |
| |
| if 'INTERFACE_COMPILE_OPTIONS' in tgt.properties: |
| res.public_compile_opts += [x for x in tgt.properties['INTERFACE_COMPILE_OPTIONS'] if x] |
| |
| if 'IMPORTED_CONFIGURATIONS' in tgt.properties: |
| cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x] |
| cfg = cfgs[0] |
| |
| if is_debug: |
| if 'DEBUG' in cfgs: |
| cfg = 'DEBUG' |
| elif 'RELEASE' in cfgs: |
| cfg = 'RELEASE' |
| else: |
| if 'RELEASE' in cfgs: |
| cfg = 'RELEASE' |
| |
| if f'IMPORTED_IMPLIB_{cfg}' in tgt.properties: |
| res.libraries += [x for x in tgt.properties[f'IMPORTED_IMPLIB_{cfg}'] if x] |
| elif 'IMPORTED_IMPLIB' in tgt.properties: |
| res.libraries += [x for x in tgt.properties['IMPORTED_IMPLIB'] if x] |
| elif f'IMPORTED_LOCATION_{cfg}' in tgt.properties: |
| res.libraries += [x for x in tgt.properties[f'IMPORTED_LOCATION_{cfg}'] if x] |
| elif 'IMPORTED_LOCATION' in tgt.properties: |
| res.libraries += [x for x in tgt.properties['IMPORTED_LOCATION'] if x] |
| |
| if 'LINK_LIBRARIES' in tgt.properties: |
| targets += [x for x in tgt.properties['LINK_LIBRARIES'] if x] |
| if 'INTERFACE_LINK_LIBRARIES' in tgt.properties: |
| targets += [x for x in tgt.properties['INTERFACE_LINK_LIBRARIES'] if x] |
| |
| if f'IMPORTED_LINK_DEPENDENT_LIBRARIES_{cfg}' in tgt.properties: |
| targets += [x for x in tgt.properties[f'IMPORTED_LINK_DEPENDENT_LIBRARIES_{cfg}'] if x] |
| elif 'IMPORTED_LINK_DEPENDENT_LIBRARIES' in tgt.properties: |
| targets += [x for x in tgt.properties['IMPORTED_LINK_DEPENDENT_LIBRARIES'] if x] |
| |
| processed_targets += [curr] |
| |
| res.include_directories = sorted(set(res.include_directories)) |
| res.link_flags = sorted(set(res.link_flags)) |
| res.public_compile_opts = sorted(set(res.public_compile_opts)) |
| res.libraries = sorted(set(res.libraries)) |
| |
| return res |