Skip to content

Commit

Permalink
InternalDependency: Add as_link_whole() method
Browse files Browse the repository at this point in the history
  • Loading branch information
xclaesse committed Sep 15, 2020
1 parent b872eea commit 67c0ec1
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 0 deletions.
7 changes: 7 additions & 0 deletions docs/markdown/Reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -2426,6 +2426,13 @@ an external dependency with the following methods:
the value of `include_type` to `value`. The `value` argument is optional and
defaults to `'preserve'`.

- `as_link_whole()` *Since 0.56.0* Only dependencies created with
`declare_dependency()`, returns a copy of the dependency object with all
link_with arguments changed to link_whole. This is useful for example for
fallback dependency from a subproject built with `default_library=static`.
Note that all `link_with` objects must be static libraries otherwise an error
will be raised when trying to `link_whole` a shared library.

- `partial_dependency(compile_args : false, link_args : false, links
: false, includes : false, sources : false)` *(since 0.46.0)*: returns
a new dependency object with the same name, version, found status,
Expand Down
12 changes: 12 additions & 0 deletions docs/markdown/snippets/as_link_whole.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## `dep.as_link_whole()`

Dependencies created with `declare_dependency()` now has new method `as_link_whole()`.
It returns a copy of the dependency object with all link_with arguments changed
to link_whole. This is useful for example for fallback dependency from a
subproject built with `default_library=static`.

```meson
somelib = static_library('somelib', ...)
dep = declare_dependency(..., link_with: somelib)
library('someotherlib', ..., dependencies: dep.as_link_whole())
```
5 changes: 5 additions & 0 deletions mesonbuild/dependencies/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,11 @@ def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[s
return val
raise DependencyException('Could not get an internal variable and no default provided for {!r}'.format(self))

def generate_link_whole_dependency(self) -> T.Type['Dependency']:
new_dep = copy.deepcopy(self)
new_dep.whole_libraries += new_dep.libraries
new_dep.libraries = []
return new_dep

class HasNativeKwarg:
def __init__(self, kwargs):
Expand Down
10 changes: 10 additions & 0 deletions mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def __init__(self, dep, pv):
'partial_dependency': self.partial_dependency_method,
'include_type': self.include_type_method,
'as_system': self.as_system_method,
'as_link_whole': self.as_link_whole_method,
})

def found(self):
Expand Down Expand Up @@ -511,6 +512,15 @@ def as_system_method(self, args, kwargs):
new_dep = self.held_object.generate_system_dependency(new_is_system)
return DependencyHolder(new_dep, self.subproject)

@FeatureNew('dep.as_link_whole', '0.56.0')
@permittedKwargs({})
@noPosargs
def as_link_whole_method(self, args, kwargs):
if not isinstance(self.held_object, InternalDependency):
raise InterpreterException('as_link_whole method is only supported on declare_dependency() objects')
new_dep = self.held_object.generate_link_whole_dependency()
return DependencyHolder(new_dep, self.subproject)

class ExternalProgramHolder(InterpreterObject, ObjectHolder):
def __init__(self, ep, subproject, backend=None):
InterpreterObject.__init__(self)
Expand Down
10 changes: 10 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7294,6 +7294,16 @@ def test_lookup_system_after_broken_fallback(self):
'''))
self.init(d, override_envvars={'PKG_CONFIG_LIBDIR': privatedir})

def test_as_link_whole(self):
testdir = os.path.join(self.unit_test_dir, '79 as link whole')
self.init(testdir)
with open(os.path.join(self.privatedir, 'bar1.pc')) as f:
content = f.read()
self.assertIn('-lfoo', content)
with open(os.path.join(self.privatedir, 'bar2.pc')) as f:
content = f.read()
self.assertNotIn('-lfoo', content)

class BaseLinuxCrossTests(BasePlatformTests):
# Don't pass --libdir when cross-compiling. We have tests that
# check whether meson auto-detects it correctly.
Expand Down
6 changes: 6 additions & 0 deletions test cases/unit/79 as link whole/bar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int bar(void);

int bar(void)
{
return 0;
}
6 changes: 6 additions & 0 deletions test cases/unit/79 as link whole/foo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int foo(void);

int foo(void)
{
return 0;
}
11 changes: 11 additions & 0 deletions test cases/unit/79 as link whole/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
project('as-link-whole', 'c')

foo = static_library('foo', 'foo.c', install: true)
dep = declare_dependency(link_with: foo)
bar1 = library('bar1', 'bar.c', dependencies: dep)
bar2 = library('bar2', 'bar.c', dependencies: dep.as_link_whole())

# bar1.pc should have -lfoo but not bar2.pc
pkg = import('pkgconfig')
pkg.generate(bar1)
pkg.generate(bar2)

0 comments on commit 67c0ec1

Please sign in to comment.