Skip to content

Commit

Permalink
Select static from both_libraries in internal dep
Browse files Browse the repository at this point in the history
Add `.as_static()` method to internal dependencies.

Internal dependencies can now choose between static and shared version
of a `both_libraries` linked library. This allows to use the same
dependency objects for building either a static or a shared library from
the same hierarchy of dependencies.
  • Loading branch information
bruchar1 committed Aug 11, 2023
1 parent 03a2a3a commit 1ea5e1a
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 0 deletions.
10 changes: 10 additions & 0 deletions docs/markdown/snippets/dep_as_static.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Allow the use of static version of `both_libraries` in internal dependencies

Internal dependencies can now choose the static version
of a `both_libraries` linked library. This allows to use the same
dependency objects for building either a static or a shared library from
the same hierarchy of dependencies.

`dep` object returned by [[declare_dependency]] now has `.as_static()` method,
to convert it to a dependency that prefer the `static` version of the linked
[[both_libraries]] targets.
13 changes: 13 additions & 0 deletions docs/yaml/objects/dep.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,16 @@ methods:
pkgconfig_define:
type: list[str]
description: See [[dep.get_pkgconfig_variable]]

- name: as_static
returns: dep
since: 1.3.0
description: |
Only 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
9 changes: 9 additions & 0 deletions mesonbuild/dependencies/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,15 @@ 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

class HasNativeKwarg:
def __init__(self, kwargs: T.Dict[str, T.Any]):
self.for_machine = self.get_for_machine_from_kwargs(kwargs)
Expand Down
16 changes: 16 additions & 0 deletions mesonbuild/interpreter/interpreterobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class EnvironmentSeparatorKW(TypedDict):

separator: str

class InternalDependencyAsStaticKW(TypedDict):

recursive: bool

_ERROR_MSG_KW: KwargInfo[T.Optional[str]] = KwargInfo('error_message', (str, NoneType))


Expand Down Expand Up @@ -455,6 +459,7 @@ 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,
})

def found(self) -> bool:
Expand Down Expand Up @@ -559,6 +564,17 @@ 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.3.0')
@noPosargs
@typed_kwargs(
'dependency.as_static',
KwargInfo('recursive', bool, default=False),
)
def as_static_method(self, args: T.List[TYPE_var], kwargs: InternalDependencyAsStaticKW) -> 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'])

_EXTPROG = T.TypeVar('_EXTPROG', bound=ExternalProgram)

class _ExternalProgramHolder(ObjectHolder[_EXTPROG]):
Expand Down
4 changes: 4 additions & 0 deletions test cases/common/267 dep as_static/lib1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int libfunc1(void)
{
return 1;
}
3 changes: 3 additions & 0 deletions test cases/common/267 dep as_static/lib1.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
EXPORTS

libfunc1 @1
4 changes: 4 additions & 0 deletions test cases/common/267 dep as_static/lib2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int libfunc2(void)
{
return 2;
}
3 changes: 3 additions & 0 deletions test cases/common/267 dep as_static/lib2.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
EXPORTS

libfunc2 @2
4 changes: 4 additions & 0 deletions test cases/common/267 dep as_static/lib3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int libfunc3(void)
{
return 3;
}
3 changes: 3 additions & 0 deletions test cases/common/267 dep as_static/lib3.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
EXPORTS

libfunc3 @3
4 changes: 4 additions & 0 deletions test cases/common/267 dep as_static/lib4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
int libfunc4(void)
{
return 4;
}
9 changes: 9 additions & 0 deletions test cases/common/267 dep as_static/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
int libfunc1(void);
int libfunc2(void);
int libfunc3(void);
int libfunc4(void);

int main(void)
{
return libfunc1() + libfunc2() + libfunc3() + libfunc4() == 10 ? 0 : 1;
}
31 changes: 31 additions & 0 deletions test cases/common/267 dep as_static/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
project(
'as_static',
['c'],
meson_version: '>= 1.3.0',
)

lib1 = library('lib1', 'lib1.c', vs_module_defs: 'lib1.def')
dep1 = declare_dependency(link_with: lib1)

lib2 = both_libraries('lib2', 'lib2.c', vs_module_defs: 'lib2.def')
dep2 = declare_dependency(link_with: lib2)

lib3 = shared_library('lib3', 'lib3.c', vs_module_defs: 'lib3.def')
dep3 = declare_dependency(link_with: lib3)

lib4 = static_library('lib4', 'lib4.c')
dep4 = declare_dependency(link_with: lib4)


dep_default = declare_dependency(dependencies: [dep1, dep2, dep3, dep4])
main_default = executable('main_default', 'main.c', dependencies: [dep_default])
test('default', main_default)

dep_static = declare_dependency(dependencies: [dep1, dep2, dep3, dep4]).as_static(recursive: true)
main_static = executable('main_static', 'main.c', dependencies: [dep_static])
test('static', main_static)


# FIXME: this doesn't really test that expected lib versions are linked,
# but I don't know how I could test this...
# Maybe should I write a unit test for that?
11 changes: 11 additions & 0 deletions test cases/common/267 dep as_static/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"matrix": {
"options": {
"default_library": [
{ "val": "shared" },
{ "val": "static" },
{ "val": "both" }
]
}
}
}

0 comments on commit 1ea5e1a

Please sign in to comment.