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 Oct 10, 2023
1 parent 3af0632 commit a9d660d
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 2 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
13 changes: 11 additions & 2 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ def get_target_macos_dylib_install_name(ld) -> str:
name.append('.dylib')
return ''.join(name)


def extract_targets_as_list(kwargs: T.Dict[str, T.Any], key: str, self_libs: T.List[LibTypes]) -> T.List[LibTypes]:
lib_list = listify(kwargs.get(key, [])) + self_libs
return [t.get_default_object() if isinstance(t, BothLibraries) else t for t in lib_list]


class InvalidArguments(MesonException):
pass

Expand Down Expand Up @@ -769,8 +775,8 @@ def __init__(
# we have to call process_compilers() first and we need to process libraries
# from link_with and link_whole first.
# See https://github.com/mesonbuild/meson/pull/11957#issuecomment-1629243208.
link_targets = extract_as_list(kwargs, 'link_with') + self.link_targets
link_whole_targets = extract_as_list(kwargs, 'link_whole') + self.link_whole_targets
link_targets = extract_targets_as_list(kwargs, 'link_with', self.link_targets)
link_whole_targets = extract_targets_as_list(kwargs, 'link_whole', self.link_whole_targets)
self.link_targets.clear()
self.link_whole_targets.clear()
self.link(link_targets)
Expand Down Expand Up @@ -2483,6 +2489,9 @@ def get_default_object(self) -> BuildTarget:
return self.static
raise MesonBugException(f'self._preferred_library == "{self._preferred_library}" is neither "shared" nor "static".')

def get_id(self) -> str:
return self.get_default_object().get_id()

class CommandBase:

depend_files: T.List[File]
Expand Down
9 changes: 9 additions & 0 deletions mesonbuild/dependencies/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,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
1 change: 1 addition & 0 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ def func_files(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwa
KwargInfo('version', (str, NoneType)),
KwargInfo('objects', ContainerTypeInfo(list, build.ExtractedObjects), listify=True, default=[], since='1.1.0'),
)
@noSecondLevelHolderResolving
def func_declare_dependency(self, node: mparser.BaseNode, args: T.List[TYPE_var],
kwargs: kwtypes.FuncDeclareDependency) -> dependencies.Dependency:
deps = kwargs['dependencies']
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 @@ -566,6 +571,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 + NUMBER;
}
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 + NUMBER;
}
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;
}
10 changes: 10 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,10 @@
int libfunc1(void);
int libfunc2(void);
int libfunc3(void);
int libfunc4(void);

int main(void)
{
int sum = libfunc1() + libfunc2() + libfunc3() + libfunc4();
return sum == EXPECTED ? 0 : sum;
}
47 changes: 47 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,47 @@
project(
'as_static',
['c'],
meson_version: '>= 1.3.0',
)

lib1 = library('lib1', 'lib1.c', vs_module_defs: 'lib1.def', c_static_args: ['-DNUMBER=100'], c_shared_args: ['-DNUMBER=1000'])
dep1 = declare_dependency(link_with: lib1)

lib2 = both_libraries('lib2', 'lib2.c', vs_module_defs: 'lib2.def', c_static_args: ['-DNUMBER=100'], c_shared_args: ['-DNUMBER=1000'])
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)


if get_option('default_library') == 'static'
lib1_n = 101
else
lib1_n = 1001 # shared or both will use shared
endif
lib2_n = 1002 # shared
lib3_n = 3
lib4_n = 4

expected = lib1_n + lib2_n + lib3_n + lib4_n
dep_default = declare_dependency(dependencies: [dep1, dep2, dep3, dep4])
main_default = executable('main_default', 'main.c', dependencies: [dep_default], c_args: ['-DEXPECTED=@0@'.format(expected)])
test('default', main_default)


if get_option('default_library') == 'shared'
lib1_n = 1001
else
lib1_n = 101 # static or both will use static
endif
lib2_n = 102 # static
lib3_n = 3
lib4_n = 4

expected = lib1_n + lib2_n + lib3_n + lib4_n
dep_static = declare_dependency(dependencies: [dep1, dep2, dep3, dep4]).as_static(recursive: true)
main_static = executable('main_static', 'main.c', dependencies: [dep_static], c_args: ['-DEXPECTED=@0@'.format(expected)])
test('static', main_static)
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 a9d660d

Please sign in to comment.