The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.8 KiB
119 lines
4.8 KiB
# 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
|
|
|