From 3a960023d3e78d04651850178db96c7d742725e6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 29 Mar 2022 13:52:03 +0200 Subject: [PATCH] interpreter: new function add_project_dependencies() This function can be used to add fundamental dependencies such as glib to all build products in one fell swoop. This can be useful whenever, due to a project's coding conventions, it is not really possible to compile any source file without including the dependency. Signed-off-by: Paolo Bonzini --- data/syntax-highlighting/vim/syntax/meson.vim | 1 + .../snippets/add_project_dependencies.md | 11 ++++++++++ .../functions/add_project_dependencies.yaml | 16 ++++++++++++++ mesonbuild/ast/interpreter.py | 1 + mesonbuild/dependencies/base.py | 6 +++++ mesonbuild/interpreter/interpreter.py | 22 +++++++++++++++++++ .../251 add_project_dependencies/inc/lib.h | 2 ++ .../common/251 add_project_dependencies/lib.c | 14 ++++++++++++ .../251 add_project_dependencies/main.c | 5 +++++ .../251 add_project_dependencies/meson.build | 22 +++++++++++++++++++ 10 files changed, 100 insertions(+) create mode 100644 docs/markdown/snippets/add_project_dependencies.md create mode 100644 docs/yaml/functions/add_project_dependencies.yaml create mode 100644 test cases/common/251 add_project_dependencies/inc/lib.h create mode 100644 test cases/common/251 add_project_dependencies/lib.c create mode 100644 test cases/common/251 add_project_dependencies/main.c create mode 100644 test cases/common/251 add_project_dependencies/meson.build diff --git a/data/syntax-highlighting/vim/syntax/meson.vim b/data/syntax-highlighting/vim/syntax/meson.vim index 2cb49e34c17d..3b858bd0636b 100644 --- a/data/syntax-highlighting/vim/syntax/meson.vim +++ b/data/syntax-highlighting/vim/syntax/meson.vim @@ -68,6 +68,7 @@ syn keyword mesonBuiltin \ add_global_link_arguments \ add_languages \ add_project_arguments + \ add_project_dependencies \ add_project_link_arguments \ add_test_setup \ alias_target diff --git a/docs/markdown/snippets/add_project_dependencies.md b/docs/markdown/snippets/add_project_dependencies.md new file mode 100644 index 000000000000..193ea55a2c23 --- /dev/null +++ b/docs/markdown/snippets/add_project_dependencies.md @@ -0,0 +1,11 @@ +## `add_project_dependencies()` function + +Dependencies can now be added to all build products using +`add_project_dependencies()`. This can be useful in several +cases: + +* with special dependencies such as `dependency('threads')` +* with system libraries such as `find_library('m')` +* with the `include_directories` keyword argument of +`declare_dependency()`, to add both source and build +directories to the include search path diff --git a/docs/yaml/functions/add_project_dependencies.yaml b/docs/yaml/functions/add_project_dependencies.yaml new file mode 100644 index 000000000000..03420c51c4e3 --- /dev/null +++ b/docs/yaml/functions/add_project_dependencies.yaml @@ -0,0 +1,16 @@ +name: add_project_dependencies +since: 0.63.0 +returns: void +description: | + Adds arguments to the compiler and linker command line, so that the + given set of dependencies is included in all build products for this + project. + + +varargs: + type: dep + name: dependencies + description: The dependencies to add; if internal dependencies are included, + they must not include any built object. + +kwargs_inherit: add_global_arguments diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py index 6128eef57393..2e18a6abe8ed 100644 --- a/mesonbuild/ast/interpreter.py +++ b/mesonbuild/ast/interpreter.py @@ -114,6 +114,7 @@ def __init__(self, source_root: str, subdir: str, subproject: str, visitors: T.O 'add_global_arguments': self.func_do_nothing, 'add_global_link_arguments': self.func_do_nothing, 'add_project_arguments': self.func_do_nothing, + 'add_project_dependencies': self.func_do_nothing, 'add_project_link_arguments': self.func_do_nothing, 'message': self.func_do_nothing, 'generator': self.func_do_nothing, diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index c2a274ebe1c6..97a19be2c6b5 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -165,6 +165,9 @@ def get_version(self) -> str: else: return 'unknown' + def get_include_dirs(self) -> T.List['IncludeDirs']: + return [] + def get_include_type(self) -> str: return self.include_type @@ -298,6 +301,9 @@ def get_partial_dependency(self, *, compile_args: bool = False, final_link_args, final_libraries, final_whole_libraries, final_sources, final_deps, self.variables, [], []) + def get_include_dirs(self) -> T.List['IncludeDirs']: + return self.include_directories + def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None, configtool: T.Optional[str] = None, internal: T.Optional[str] = None, default_value: T.Optional[str] = None, diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 0cf0980c522f..17d21caf64ff 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -346,6 +346,7 @@ def build_func_dict(self) -> None: 'add_global_link_arguments': self.func_add_global_link_arguments, 'add_languages': self.func_add_languages, 'add_project_arguments': self.func_add_project_arguments, + 'add_project_dependencies': self.func_add_project_dependencies, 'add_project_link_arguments': self.func_add_project_link_arguments, 'add_test_setup': self.func_add_test_setup, 'alias_target': self.func_alias_target, @@ -2654,6 +2655,27 @@ def func_add_project_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T def func_add_project_link_arguments(self, node: mparser.FunctionNode, args: T.Tuple[T.List[str]], kwargs: 'kwargs.FuncAddProjectArgs') -> None: self._add_project_arguments(node, self.build.projects_link_args[kwargs['native']], args[0], kwargs) + @FeatureNew('add_project_dependencies', '0.63.0') + @typed_pos_args('add_project_dependencies', varargs=dependencies.Dependency) + @typed_kwargs('add_project_dependencies', NATIVE_KW, LANGUAGE_KW) + def func_add_project_dependencies(self, node: mparser.FunctionNode, args: T.Tuple[T.List[dependencies.Dependency]], kwargs: 'kwargs.FuncAddProjectArgs') -> None: + for_machine = kwargs['native'] + for lang in kwargs['language']: + if lang not in self.compilers[for_machine]: + raise InvalidCode(f'add_project_dependencies() called before add_language() for language "{lang}"') + + for d in dependencies.get_leaf_external_dependencies(args[0]): + compile_args = list(d.get_compile_args()) + system_incdir = d.get_include_type() == 'system' + for i in d.get_include_dirs(): + for lang in kwargs['language']: + comp = self.coredata.compilers[for_machine][lang] + for idir in i.to_string_list(self.environment.get_source_dir()): + compile_args.extend(comp.get_include_args(idir, system_incdir)) + + self._add_project_arguments(node, self.build.projects_args[for_machine], compile_args, kwargs) + self._add_project_arguments(node, self.build.projects_link_args[for_machine], d.get_link_args(), kwargs) + def _warn_about_builtin_args(self, args: T.List[str]) -> None: # -Wpedantic is deliberately not included, since some people want to use it but not use -Wextra # see e.g. diff --git a/test cases/common/251 add_project_dependencies/inc/lib.h b/test cases/common/251 add_project_dependencies/inc/lib.h new file mode 100644 index 000000000000..ceca99f7339a --- /dev/null +++ b/test cases/common/251 add_project_dependencies/inc/lib.h @@ -0,0 +1,2 @@ +#pragma once +extern int ok(void); diff --git a/test cases/common/251 add_project_dependencies/lib.c b/test cases/common/251 add_project_dependencies/lib.c new file mode 100644 index 000000000000..ac46bfcff69f --- /dev/null +++ b/test cases/common/251 add_project_dependencies/lib.c @@ -0,0 +1,14 @@ +#include +#include + +#ifndef DEFINED +#error expected compile_arg not found +#endif + +double zero; +int ok(void) { + void * something = deflate; + if(something != 0) + return 0; + return (int)cos(zero); +} diff --git a/test cases/common/251 add_project_dependencies/main.c b/test cases/common/251 add_project_dependencies/main.c new file mode 100644 index 000000000000..93b7f72bd41b --- /dev/null +++ b/test cases/common/251 add_project_dependencies/main.c @@ -0,0 +1,5 @@ +#include "lib.h" + +int main(void) { + return ok(); +} diff --git a/test cases/common/251 add_project_dependencies/meson.build b/test cases/common/251 add_project_dependencies/meson.build new file mode 100644 index 000000000000..4047e6d1c872 --- /dev/null +++ b/test cases/common/251 add_project_dependencies/meson.build @@ -0,0 +1,22 @@ +project('zlib system dependency', 'c') + +cc = meson.get_compiler('c') + +m = cc.find_library('m', required: false) +add_project_dependencies(m, language: ['c']) + +z = dependency('zlib', method: 'system', required: false) +if not z.found() + error('MESON_SKIP_TEST zlib not present') +endif + +z_c_args = z.partial_dependency(compile_args: true, includes: true) +add_project_dependencies(z_c_args, language: 'c', native: false) + +global_dep = declare_dependency(include_directories: include_directories('inc'), + compile_args: '-DDEFINED') +add_project_dependencies(global_dep, language: 'c', native: false) + +lib = static_library('rary', 'lib.c') +exe = executable('prog', 'main.c', link_with: lib, dependencies: z) +test('test', exe)