aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-03-09 13:20:52 -0800
committerEli Schwartz <eschwartz93@gmail.com>2022-08-18 21:57:36 -0400
commite15f15d90426aee0efd63e811a4719022b8ecfcf (patch)
tree431f45256f0d40d7365e64f6285c439203cc0228
parent3f63827527e1f9a6175e3457a0a0902825d4b79e (diff)
downloadmeson-e15f15d90426aee0efd63e811a4719022b8ecfcf.zip
meson-e15f15d90426aee0efd63e811a4719022b8ecfcf.tar.gz
meson-e15f15d90426aee0efd63e811a4719022b8ecfcf.tar.bz2
modules/pkgconfig: get rid of modifications to the BuildTarget objects
This would tack on extra attributes for meta data tracking. Do that with our own datastructures instead
-rw-r--r--mesonbuild/modules/pkgconfig.py64
1 files changed, 40 insertions, 24 deletions
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index aeb77c6..859ac3f 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -1,4 +1,4 @@
-# Copyright 2015 The Meson development team
+# Copyright 2015-2022 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
from __future__ import annotations
from collections import defaultdict
+from dataclasses import dataclass
from pathlib import PurePath
import os
import typing as T
@@ -34,6 +35,7 @@ if T.TYPE_CHECKING:
from typing_extensions import TypedDict
from . import ModuleState
+ from .. import mparser
from ..interpreter import Interpreter
ANY_DEP = T.Union[dependencies.Dependency, build.BuildTargetTypes, str]
@@ -62,8 +64,6 @@ if T.TYPE_CHECKING:
unescaped_uninstalled_variables: T.Dict[str, str]
-already_warned_objs = set()
-
_PKG_LIBRARIES: KwargInfo[T.List[T.Union[str, dependencies.Dependency, build.SharedLibrary, build.StaticLibrary, build.CustomTarget, build.CustomTargetIndex]]] = KwargInfo(
'libraries',
ContainerTypeInfo(list, (str, dependencies.Dependency,
@@ -86,8 +86,17 @@ def _as_str(obj: object) -> str:
return obj
+@dataclass
+class MetaData:
+
+ filebase: str
+ display_name: str
+ location: mparser.BaseNode
+ warned: bool = False
+
+
class DependenciesHelper:
- def __init__(self, state: ModuleState, name: str) -> None:
+ def __init__(self, state: ModuleState, name: str, metadata: T.Dict[str, MetaData]) -> None:
self.state = state
self.name = name
self.pub_libs: T.List[LIBS] = []
@@ -97,6 +106,7 @@ class DependenciesHelper:
self.cflags: T.List[str] = []
self.version_reqs: T.DefaultDict[str, T.Set[str]] = defaultdict(set)
self.link_whole_targets: T.List[T.Union[build.CustomTarget, build.CustomTargetIndex, build.StaticLibrary]] = []
+ self.metadata = metadata
def add_pub_libs(self, libs: T.Sequence[ANY_DEP]) -> None:
p_libs, reqs, cflags = self._process_libs(libs, True)
@@ -115,22 +125,22 @@ class DependenciesHelper:
def add_priv_reqs(self, reqs: T.Sequence[T.Union[str, dependencies.Dependency]]) -> None:
self.priv_reqs += self._process_reqs(reqs)
- def _check_generated_pc_deprecation(self, obj) -> None:
- if not hasattr(obj, 'generated_pc_warn'):
+ def _check_generated_pc_deprecation(self, obj: T.Union[build.CustomTarget, build.CustomTargetIndex, build.StaticLibrary, build.SharedLibrary]) -> None:
+ if obj.get_id() in self.metadata:
return
- name = obj.generated_pc_warn[0]
- if (name, obj.name) in already_warned_objs:
+ data = self.metadata[obj.get_id()]
+ if data.warned:
return
mlog.deprecation('Library', mlog.bold(obj.name), 'was passed to the '
'"libraries" keyword argument of a previous call '
'to generate() method instead of first positional '
- 'argument.', 'Adding', mlog.bold(obj.generated_pc),
+ 'argument.', 'Adding', mlog.bold(data.display_name),
'to "Requires" field, but this is a deprecated '
'behaviour that will change in a future version '
'of Meson. Please report the issue if this '
'warning cannot be avoided in your case.',
- location=obj.generated_pc_warn[1])
- already_warned_objs.add((name, obj.name))
+ location=data.location)
+ data.warned = True
def _process_reqs(self, reqs: T.Sequence[T.Union[str, dependencies.Dependency]]) -> T.List[str]:
'''Returns string names of requirements'''
@@ -138,9 +148,10 @@ class DependenciesHelper:
for obj in mesonlib.listify(reqs):
if not isinstance(obj, str):
FeatureNew.single_use('pkgconfig.generate requirement from non-string object', '0.46.0', self.state.subproject)
- if hasattr(obj, 'generated_pc'):
+ if (isinstance(obj, (build.CustomTarget, build.CustomTargetIndex, build.SharedLibrary, build.StaticLibrary))
+ and obj.get_id() in self.metadata):
self._check_generated_pc_deprecation(obj)
- processed_reqs.append(obj.generated_pc)
+ processed_reqs.append(self.metadata[obj.get_id()].filebase)
elif isinstance(obj, dependencies.PkgConfigDependency):
if obj.found():
processed_reqs.append(obj.name)
@@ -170,9 +181,10 @@ class DependenciesHelper:
processed_reqs: T.List[str] = []
processed_cflags: T.List[str] = []
for obj in libs:
- if hasattr(obj, 'generated_pc'):
+ if (isinstance(obj, (build.CustomTarget, build.CustomTargetIndex, build.SharedLibrary, build.StaticLibrary))
+ and obj.get_id() in self.metadata):
self._check_generated_pc_deprecation(obj)
- processed_reqs.append(obj.generated_pc)
+ processed_reqs.append(self.metadata[obj.get_id()].filebase)
elif isinstance(obj, dependencies.ValgrindDependency):
pass
elif isinstance(obj, dependencies.PkgConfigDependency):
@@ -290,9 +302,9 @@ class DependenciesHelper:
# We can't just check if 'x' is excluded because we could have copies of
# the same SharedLibrary object for example.
def _ids(x: T.Union[str, build.CustomTarget, build.CustomTargetIndex, build.StaticLibrary]) -> T.Iterable[str]:
- if hasattr(x, 'generated_pc'):
- yield x.generated_pc
if isinstance(x, build.Target):
+ if x.get_id() in self.metadata:
+ yield self.metadata[x.get_id()].display_name
yield x.get_id()
yield x
@@ -349,6 +361,10 @@ class PkgConfigModule(ExtensionModule):
INFO = ModuleInfo('pkgconfig')
+ # Track already generated pkg-config files This is stored as a class
+ # variable so that multiple `import()`s share metadata
+ _metadata: T.ClassVar[T.Dict[str, MetaData]] = {}
+
def __init__(self, interpreter: Interpreter):
super().__init__(interpreter)
self.methods.update({
@@ -648,7 +664,7 @@ class PkgConfigModule(ExtensionModule):
if mainlib:
libraries.insert(0, mainlib)
- deps = DependenciesHelper(state, filebase)
+ deps = DependenciesHelper(state, filebase, self._metadata)
deps.add_pub_libs(libraries)
deps.add_priv_libs(kwargs['libraries_private'])
deps.add_pub_reqs(kwargs['requires'])
@@ -704,16 +720,16 @@ class PkgConfigModule(ExtensionModule):
# libraries instead of just the main one. Keep doing that but warn if
# anyone is relying on that deprecated behaviour.
if mainlib:
- if not hasattr(mainlib, 'generated_pc'):
- mainlib.generated_pc = filebase
+ if mainlib.get_id() not in self._metadata:
+ self._metadata[mainlib.get_id()] = MetaData(
+ filebase, name, state.current_node)
else:
mlog.warning('Already generated a pkg-config file for', mlog.bold(mainlib.name))
else:
for lib in deps.pub_libs:
- if not isinstance(lib, str) and not hasattr(lib, 'generated_pc'):
- lib.generated_pc = filebase
- location = state.current_node
- lib.generated_pc_warn = [name, location]
+ if not isinstance(lib, str) and lib.get_id() not in self._metadata:
+ self._metadata[lib.get_id()] = MetaData(
+ filebase, name, state.current_node)
return ModuleReturnValue(res, [res])