blob: bb5faa3959d1c9b958d918285430864388e2ab37 [file] [log] [blame]
# 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