mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
This replaces all of the Apache blurbs at the start of each file with an `# SPDX-License-Identifier: Apache-2.0` string. It also fixes existing uses to be consistent in capitalization, and to be placed above any copyright notices. This removes nearly 3000 lines of boilerplate from the project (only python files), which no developer cares to look at. SPDX is in common use, particularly in the Linux kernel, and is the recommended format for Meson's own `project(license: )` field
147 lines
6.4 KiB
Python
147 lines
6.4 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# Copyright 2013-2021 The Meson development team
|
|
# Copyright © 2021-2023 Intel Corporation
|
|
|
|
from __future__ import annotations
|
|
|
|
import functools
|
|
import typing as T
|
|
|
|
from .base import DependencyException, DependencyMethods
|
|
from .base import process_method_kw
|
|
from .base import BuiltinDependency, SystemDependency
|
|
from .cmake import CMakeDependency
|
|
from .framework import ExtraFrameworkDependency
|
|
from .pkgconfig import PkgConfigDependency
|
|
|
|
if T.TYPE_CHECKING:
|
|
from .base import ExternalDependency
|
|
from .configtool import ConfigToolDependency
|
|
from ..environment import Environment
|
|
from ..mesonlib import MachineChoice
|
|
|
|
DependencyGenerator = T.Callable[[], ExternalDependency]
|
|
FactoryFunc = T.Callable[
|
|
[
|
|
'Environment',
|
|
MachineChoice,
|
|
T.Dict[str, T.Any],
|
|
T.List[DependencyMethods]
|
|
],
|
|
T.List[DependencyGenerator]
|
|
]
|
|
|
|
WrappedFactoryFunc = T.Callable[
|
|
[
|
|
'Environment',
|
|
MachineChoice,
|
|
T.Dict[str, T.Any]
|
|
],
|
|
T.List[DependencyGenerator]
|
|
]
|
|
|
|
# This should be str, Environment, T.Dict[str, T.Any], T.Optional[str]
|
|
# But if you try that, you get error: Cannot infer type of lambda
|
|
CmakeDependencyFunc = T.Callable[..., CMakeDependency]
|
|
|
|
class DependencyFactory:
|
|
|
|
"""Factory to get dependencies from multiple sources.
|
|
|
|
This class provides an initializer that takes a set of names and classes
|
|
for various kinds of dependencies. When the initialized object is called
|
|
it returns a list of callables return Dependency objects to try in order.
|
|
|
|
:name: The name of the dependency. This will be passed as the name
|
|
parameter of the each dependency unless it is overridden on a per
|
|
type basis.
|
|
:methods: An ordered list of DependencyMethods. This is the order
|
|
dependencies will be returned in unless they are removed by the
|
|
_process_method function
|
|
:*_name: This will overwrite the name passed to the corresponding class.
|
|
For example, if the name is 'zlib', but cmake calls the dependency
|
|
'Z', then using `cmake_name='Z'` will pass the name as 'Z' to cmake.
|
|
:*_class: A *type* or callable that creates a class, and has the
|
|
signature of an ExternalDependency
|
|
:system_class: If you pass DependencyMethods.SYSTEM in methods, you must
|
|
set this argument.
|
|
"""
|
|
|
|
def __init__(self, name: str, methods: T.List[DependencyMethods], *,
|
|
extra_kwargs: T.Optional[T.Dict[str, T.Any]] = None,
|
|
pkgconfig_name: T.Optional[str] = None,
|
|
pkgconfig_class: 'T.Type[PkgConfigDependency]' = PkgConfigDependency,
|
|
cmake_name: T.Optional[str] = None,
|
|
cmake_class: 'T.Union[T.Type[CMakeDependency], CmakeDependencyFunc]' = CMakeDependency,
|
|
configtool_class: 'T.Optional[T.Type[ConfigToolDependency]]' = None,
|
|
framework_name: T.Optional[str] = None,
|
|
framework_class: 'T.Type[ExtraFrameworkDependency]' = ExtraFrameworkDependency,
|
|
builtin_class: 'T.Type[BuiltinDependency]' = BuiltinDependency,
|
|
system_class: 'T.Type[SystemDependency]' = SystemDependency):
|
|
|
|
if DependencyMethods.CONFIG_TOOL in methods and not configtool_class:
|
|
raise DependencyException('A configtool must have a custom class')
|
|
|
|
self.extra_kwargs = extra_kwargs or {}
|
|
self.methods = methods
|
|
self.classes: T.Dict[
|
|
DependencyMethods,
|
|
T.Callable[['Environment', T.Dict[str, T.Any]], ExternalDependency]
|
|
] = {
|
|
# Just attach the correct name right now, either the generic name
|
|
# or the method specific name.
|
|
DependencyMethods.EXTRAFRAMEWORK: functools.partial(framework_class, framework_name or name),
|
|
DependencyMethods.PKGCONFIG: functools.partial(pkgconfig_class, pkgconfig_name or name),
|
|
DependencyMethods.CMAKE: functools.partial(cmake_class, cmake_name or name),
|
|
DependencyMethods.SYSTEM: functools.partial(system_class, name),
|
|
DependencyMethods.BUILTIN: functools.partial(builtin_class, name),
|
|
DependencyMethods.CONFIG_TOOL: None,
|
|
}
|
|
if configtool_class is not None:
|
|
self.classes[DependencyMethods.CONFIG_TOOL] = functools.partial(configtool_class, name)
|
|
|
|
@staticmethod
|
|
def _process_method(method: DependencyMethods, env: 'Environment', for_machine: MachineChoice) -> bool:
|
|
"""Report whether a method is valid or not.
|
|
|
|
If the method is valid, return true, otherwise return false. This is
|
|
used in a list comprehension to filter methods that are not possible.
|
|
|
|
By default this only remove EXTRAFRAMEWORK dependencies for non-mac platforms.
|
|
"""
|
|
# Extra frameworks are only valid for macOS and other apple products
|
|
if (method is DependencyMethods.EXTRAFRAMEWORK and
|
|
not env.machines[for_machine].is_darwin()):
|
|
return False
|
|
return True
|
|
|
|
def __call__(self, env: 'Environment', for_machine: MachineChoice,
|
|
kwargs: T.Dict[str, T.Any]) -> T.List['DependencyGenerator']:
|
|
"""Return a list of Dependencies with the arguments already attached."""
|
|
methods = process_method_kw(self.methods, kwargs)
|
|
nwargs = self.extra_kwargs.copy()
|
|
nwargs.update(kwargs)
|
|
|
|
return [functools.partial(self.classes[m], env, nwargs) for m in methods
|
|
if self._process_method(m, env, for_machine)]
|
|
|
|
|
|
def factory_methods(methods: T.Set[DependencyMethods]) -> T.Callable[['FactoryFunc'], 'WrappedFactoryFunc']:
|
|
"""Decorator for handling methods for dependency factory functions.
|
|
|
|
This helps to make factory functions self documenting
|
|
>>> @factory_methods([DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE])
|
|
>>> def factory(env: Environment, for_machine: MachineChoice, kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
|
|
>>> pass
|
|
"""
|
|
|
|
def inner(func: 'FactoryFunc') -> 'WrappedFactoryFunc':
|
|
|
|
@functools.wraps(func)
|
|
def wrapped(env: 'Environment', for_machine: MachineChoice, kwargs: T.Dict[str, T.Any]) -> T.List['DependencyGenerator']:
|
|
return func(env, for_machine, kwargs, process_method_kw(methods, kwargs))
|
|
|
|
return wrapped
|
|
|
|
return inner
|