diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2020-11-23 23:03:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-24 00:03:35 +0200 |
commit | 0deab2ee9efc2ffe9e43f2787611e34656e6a304 (patch) | |
tree | fd60e29d4d91a6d566af3a0bfec1f8f6db0c2714 | |
parent | b53505a9dc2e82a5040d3427246935c50b63184b (diff) | |
download | meson-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.md | 6 | ||||
-rw-r--r-- | mesonbuild/dependencies/base.py | 13 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 23 | ||||
-rw-r--r-- | test cases/linuxlike/2 external library/meson.build | 6 |
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) |