aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-11-23 23:03:35 +0100
committerGitHub <noreply@github.com>2020-11-24 00:03:35 +0200
commit0deab2ee9efc2ffe9e43f2787611e34656e6a304 (patch)
treefd60e29d4d91a6d566af3a0bfec1f8f6db0c2714
parentb53505a9dc2e82a5040d3427246935c50b63184b (diff)
downloadmeson-0deab2ee9efc2ffe9e43f2787611e34656e6a304.zip
meson-0deab2ee9efc2ffe9e43f2787611e34656e6a304.tar.gz
meson-0deab2ee9efc2ffe9e43f2787611e34656e6a304.tar.bz2
compiler: allow non-built internal dependencies as arguments
Allow methods on the compiler object to receive internal dependencies, as long as they only specify compiler/linker arguments or other dependencies that satisfy the same requirements. This is useful if you're using internal dependencies to add special "-D" flags such as -DNCURSES_WIDECHAR, -D_XOPEN_SOURCE_EXTENDED or -DGLIB_STATIC_COMPILATION.
-rw-r--r--docs/markdown/snippets/compiler_method_internal_deps.md6
-rw-r--r--mesonbuild/dependencies/base.py13
-rw-r--r--mesonbuild/interpreter.py23
-rw-r--r--test cases/linuxlike/2 external library/meson.build6
4 files changed, 35 insertions, 13 deletions
diff --git a/docs/markdown/snippets/compiler_method_internal_deps.md b/docs/markdown/snippets/compiler_method_internal_deps.md
new file mode 100644
index 0000000..bde6b4f
--- /dev/null
+++ b/docs/markdown/snippets/compiler_method_internal_deps.md
@@ -0,0 +1,6 @@
+## Passing internal dependencies to the compiler object
+
+Methods on the compiler object (such as `compiles`, `links`, `has_header`)
+can be passed dependencies returned by `declare_dependency`, as long as they
+only specify compiler/linker arguments or other dependencies that satisfy
+the same requirements.
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index ebe5b62..9026876 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -33,7 +33,7 @@ from .. import mlog
from .. import mesonlib
from ..compilers import clib_langs
from ..envconfig import get_env_var
-from ..environment import BinaryTable, Environment, MachineInfo
+from ..environment import Environment, MachineInfo
from ..cmake import CMakeExecutor, CMakeTraceParser, CMakeException, CMakeToolchain, CMakeExecScope, check_cmake_args
from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args
@@ -84,7 +84,7 @@ def find_external_program(env: Environment, for_machine: MachineChoice, name: st
potential_path = env.lookup_binary_entry(for_machine, name)
if potential_path is not None:
mlog.debug('{} binary for {} specified from cross file, native file, '
- 'or env var as {}'.format(display_name, for_machine, potential_path))
+ 'or env var as {}'.format(display_name, for_machine, potential_path))
yield ExternalProgram.from_entry(name, potential_path)
# We never fallback if the user-specified option is no good, so
# stop returning options.
@@ -132,6 +132,9 @@ class Dependency:
s = '<{0} {1}: {2}>'
return s.format(self.__class__.__name__, self.name, self.is_found)
+ def is_built(self) -> bool:
+ return False
+
def get_compile_args(self) -> T.List[str]:
if self.include_type == 'system':
converted = []
@@ -261,6 +264,11 @@ class InternalDependency(Dependency):
setattr(result, k, copy.deepcopy(v, memo))
return result
+ def is_built(self) -> bool:
+ if self.sources or self.libraries or self.whole_libraries:
+ return True
+ return any(d.is_built() for d in self.ext_deps)
+
def get_pkgconfig_variable(self, variable_name: str, kwargs: T.Dict[str, T.Any]) -> str:
raise DependencyException('Method "get_pkgconfig_variable()" is '
'invalid for an internal dependency')
@@ -665,7 +673,6 @@ class PkgConfigDependency(ExternalDependency):
env['PKG_CONFIG_LIBDIR'] = new_pkg_config_libdir
mlog.debug('PKG_CONFIG_LIBDIR: ' + new_pkg_config_libdir)
-
def _call_pkgbin(self, args, env=None):
# Always copy the environment since we're going to modify it
# with pkg-config variables
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 5337984..83acc01 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1120,14 +1120,18 @@ class CompilerHolder(InterpreterObject):
return endl
if endl is None:
endl = ''
- tpl = msg_many if len(deps) > 1 else msg_single
names = []
for d in deps:
+ if isinstance(d, dependencies.InternalDependency):
+ continue
if isinstance(d, dependencies.ExternalLibrary):
name = '-l' + d.name
else:
name = d.name
names.append(name)
+ if not names:
+ return None
+ tpl = msg_many if len(names) > 1 else msg_single
return tpl.format(', '.join(names)) + endl
@noPosargs
@@ -1165,16 +1169,15 @@ class CompilerHolder(InterpreterObject):
def determine_dependencies(self, kwargs, endl=':'):
deps = kwargs.get('dependencies', None)
if deps is not None:
- deps = listify(deps)
final_deps = []
- for d in deps:
- try:
- d = d.held_object
- except Exception:
- pass
- if isinstance(d, InternalDependency) or not isinstance(d, Dependency):
- raise InterpreterException('Dependencies must be external dependencies')
- final_deps.append(d)
+ while deps:
+ next_deps = []
+ for d in unholder(listify(deps)):
+ if not isinstance(d, Dependency) or d.is_built():
+ raise InterpreterException('Dependencies must be external dependencies')
+ final_deps.append(d)
+ next_deps.extend(d.ext_deps)
+ deps = next_deps
deps = final_deps
return deps, self._dep_msg(deps, endl)
diff --git a/test cases/linuxlike/2 external library/meson.build b/test cases/linuxlike/2 external library/meson.build
index fbe661a..3188ebf 100644
--- a/test cases/linuxlike/2 external library/meson.build
+++ b/test cases/linuxlike/2 external library/meson.build
@@ -18,6 +18,12 @@ int main(void) {
'''
assert(cc.links(linkcode, args : '-lz', name : 'Test link against zlib'), 'Linking test failed.')
+d1 = declare_dependency(compile_args: '-DSOMETHING', link_args: '-lz')
+assert(cc.links(linkcode, dependencies : d1,
+ name : 'Test link against zlib via declare_dependency'), 'Linking test failed.')
+d2 = declare_dependency(dependencies: d1)
+assert(cc.links(linkcode, dependencies : d2,
+ name : 'Test link against zlib via indirect declare_dependency'), 'Linking test failed.')
assert(not cc.links(nolinkcode, name : 'Failing link'), 'Linking succeeded when it should have failed.')
e = executable('zprog', 'prog.c', dependencies : zlib)