From c41f08e51f500c2db1b569ed844f533d043b3d17 Mon Sep 17 00:00:00 2001 From: Charles Brunet Date: Wed, 13 Dec 2023 16:23:32 -0500 Subject: [PATCH] add .as_static and .as_shared methods to deps --- .../snippets/dep_as_shared_as_static.md | 8 ++++++ docs/yaml/objects/dep.yaml | 25 +++++++++++++++++ mesonbuild/dependencies/base.py | 18 ++++++++++++ mesonbuild/interpreter/interpreterobjects.py | 28 +++++++++++++++++++ .../common/273 both libraries/meson.build | 28 ++++++++++++++++++- 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 docs/markdown/snippets/dep_as_shared_as_static.md diff --git a/docs/markdown/snippets/dep_as_shared_as_static.md b/docs/markdown/snippets/dep_as_shared_as_static.md new file mode 100644 index 000000000000..a84e9eeaa182 --- /dev/null +++ b/docs/markdown/snippets/dep_as_shared_as_static.md @@ -0,0 +1,8 @@ +## New `as_static` and `as_shared` methods on internal dependencies + +[[@dep]] object returned by [[declare_dependency]] now has `.as_static()` and +`.as_shared()` methods, to convert to a dependency that prefers the `static` +or the `shared` version of the linked [[@both_libs]] target. + +When the same dependency is used without those methods, the +`default_both_libraries` option determines which version is used. diff --git a/docs/yaml/objects/dep.yaml b/docs/yaml/objects/dep.yaml index 52e28faca2d2..607dc9d54368 100644 --- a/docs/yaml/objects/dep.yaml +++ b/docs/yaml/objects/dep.yaml @@ -218,3 +218,28 @@ methods: pkgconfig_define: type: list[str] description: See [[dep.get_pkgconfig_variable]] + + - name: as_static + returns: dep + since: 1.4.0 + description: | + Only for dependencies created with [[declare_dependency]], + returns a copy of the dependency object that prefer the `static` version + of [[both_libraries]]. + kwargs: + recursive: + type: bool + description: If true, this is recursively applied to dependencies + + - name: as_shared + returns: dep + since: 1.4.0 + description: | + Only for dependencies created with [[declare_dependency]], + returns a copy of the dependency object that prefer the `shared` version + of [[both_libraries]]. + kwargs: + recursive: + type: bool + description: If true, this is recursively applied to dependencies + \ No newline at end of file diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 0d946b8535b4..3f0eb396e6f6 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -345,6 +345,24 @@ def generate_link_whole_dependency(self) -> Dependency: new_dep.libraries = [] return new_dep + def get_as_static(self, recursive: bool) -> Dependency: + from ..build import BothLibraries + + new_dep = copy.copy(self) + new_dep.libraries = [lib.static if isinstance(lib, BothLibraries) else lib for lib in self.libraries] + if recursive: + new_dep.ext_deps = [dep.get_as_static(True) if isinstance(dep, InternalDependency) else dep for dep in self.ext_deps] + return new_dep + + def get_as_shared(self, recursive: bool) -> Dependency: + from ..build import BothLibraries + + new_dep = copy.copy(self) + new_dep.libraries = [lib.shared if isinstance(lib, BothLibraries) else lib for lib in self.libraries] + if recursive: + new_dep.ext_deps = [dep.get_as_shared(True) if isinstance(dep, InternalDependency) else dep for dep in self.ext_deps] + return new_dep + class HasNativeKwarg: def __init__(self, kwargs: T.Dict[str, T.Any]): self.for_machine = self.get_for_machine_from_kwargs(kwargs) diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 4320cf52e924..af3ea5459377 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -41,6 +41,10 @@ class EnvironmentSeparatorKW(TypedDict): separator: str + class InternalDependencyAsKW(TypedDict): + + recursive: bool + _ERROR_MSG_KW: KwargInfo[T.Optional[str]] = KwargInfo('error_message', (str, NoneType)) @@ -455,6 +459,8 @@ def __init__(self, dep: Dependency, interpreter: 'Interpreter'): 'include_type': self.include_type_method, 'as_system': self.as_system_method, 'as_link_whole': self.as_link_whole_method, + 'as_static': self.as_static_method, + 'as_shared': self.as_shared_method, }) def found(self) -> bool: @@ -573,6 +579,28 @@ def as_link_whole_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> D new_dep = self.held_object.generate_link_whole_dependency() return new_dep + @FeatureNew('dependency.as_static', '1.4.0') + @noPosargs + @typed_kwargs( + 'dependency.as_static', + KwargInfo('recursive', bool, default=False), + ) + def as_static_method(self, args: T.List[TYPE_var], kwargs: InternalDependencyAsKW) -> Dependency: + if not isinstance(self.held_object, InternalDependency): + raise InterpreterException('as_static method is only supported on declare_dependency() objects') + return self.held_object.get_as_static(kwargs['recursive']) + + @FeatureNew('dependency.as_shared', '1.4.0') + @noPosargs + @typed_kwargs( + 'dependency.as_shared', + KwargInfo('recursive', bool, default=False), + ) + def as_shared_method(self, args: T.List[TYPE_var], kwargs: InternalDependencyAsKW) -> Dependency: + if not isinstance(self.held_object, InternalDependency): + raise InterpreterException('as_shared method is only supported on declare_dependency() objects') + return self.held_object.get_as_shared(kwargs['recursive']) + _EXTPROG = T.TypeVar('_EXTPROG', bound=ExternalProgram) class _ExternalProgramHolder(ObjectHolder[_EXTPROG]): diff --git a/test cases/common/273 both libraries/meson.build b/test cases/common/273 both libraries/meson.build index 4e3f4921c0a3..e62c17ee699c 100644 --- a/test cases/common/273 both libraries/meson.build +++ b/test cases/common/273 both libraries/meson.build @@ -77,11 +77,37 @@ test('test both libs', main) if get_option('default_library') == 'both' and get_option('default_both_libraries') == 'auto' # With those options, even if the both_libraries defaults to 'shared', # 'static' version is used when linking to the static part of another both_libraries. + + if get_option('use_dep') + main_static_deps = [with_library_dep.as_static(recursive: true)] + main_static_links = [] + else + main_static_deps = [] + main_static_links = [with_library.get_static_lib()] + endif main_static = executable( 'main_static', files('src/main.c'), c_args: [f'-DEXPECTED=0'], - link_with: with_library.get_static_lib(), + link_with: main_static_links, + dependencies: main_static_deps, ) test('test static', main_static) + + + if get_option('use_dep') + main_shared_deps = [with_library_dep.as_shared(recursive: true)] + main_shared_links = [] + else + main_shared_deps = [] + main_shared_links = [with_library.get_shared_lib()] + endif + main_shared = executable( + 'main_shared', + files('src/main.c'), + c_args: [f'-DEXPECTED=2'], + link_with: main_shared_links, + dependencies: main_shared_deps, + ) + test('test shared', main_shared) endif