diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 3fac0ff5c..0f0020350 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -1019,7 +1019,7 @@ has one argument the others don't have: ### subdir() ``` meson - void subdir(dir_name) + void subdir(dir_name, ...) ``` Enters the specified subdirectory and executes the `meson.build` file @@ -1032,6 +1032,12 @@ current build file and in all subsequent build files executed with Note that this means that each `meson.build` file in a source tree can and must only be executed once. +This function has one keyword argument. + + - `if_found` takes one or several dependency objects and will only + recurse in the subdir if they all return `true` when queried with + `.found()` + ### subproject() ``` meson diff --git a/docs/markdown/snippets/if-found.md b/docs/markdown/snippets/if-found.md new file mode 100644 index 000000000..a8d4932c3 --- /dev/null +++ b/docs/markdown/snippets/if-found.md @@ -0,0 +1,13 @@ +# Added `if_found` to subdir + +Added a new keyword argument to the `subdir` command. It is given a +list of dependency objects and the function will only recurse in the +subdirectory if they are all found. Typical usage goes like this. + + d1 = dependency('foo') # This is found + d2 = dependency('bar') # This is not found + + subdir('somedir', if_found : [d1, d2]) + +In this case the subdirectory would not be entered since `d2` could +not be found. diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index fbf9a21de..77f31056c 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1374,6 +1374,7 @@ permitted_kwargs = {'add_global_arguments': {'language'}, 'shared_library': shlib_kwargs, 'shared_module': shmod_kwargs, 'static_library': stlib_kwargs, + 'subdir': {'if_found'}, 'subproject': {'version', 'default_options'}, 'test': {'args', 'env', 'is_parallel', 'should_fail', 'timeout', 'workdir', 'suite'}, 'vcs_tag': {'input', 'output', 'fallback', 'command', 'replace_string'}, @@ -2477,7 +2478,7 @@ to directly access options of other subprojects.''') self.build.man.append(m) return m - @noKwargs + @permittedKwargs(permitted_kwargs['subdir']) def func_subdir(self, node, args, kwargs): self.validate_arguments(args, 1, [str]) if '..' in args[0]: @@ -2486,6 +2487,11 @@ to directly access options of other subprojects.''') raise InvalidArguments('Must not go into subprojects dir with subdir(), use subproject() instead.') if self.subdir == '' and args[0].startswith('meson-'): raise InvalidArguments('The "meson-" prefix is reserved and cannot be used for top-level subdir().') + for i in mesonlib.extract_as_list(kwargs, 'if_found'): + if not hasattr(i, 'found_method'): + raise InterpreterException('Object used in if_found does not have a found method.') + if not i.found_method([], {}): + return prev_subdir = self.subdir subdir = os.path.join(prev_subdir, args[0]) if os.path.isabs(subdir): diff --git a/test cases/common/165 subdir if_found/meson.build b/test cases/common/165 subdir if_found/meson.build new file mode 100644 index 000000000..2c640cfad --- /dev/null +++ b/test cases/common/165 subdir if_found/meson.build @@ -0,0 +1,11 @@ +project('subdir if found', 'c') + +found_dep = declare_dependency() +not_found_dep = dependency('nonexisting', required : false) + +subdir('nonexisting_dir', if_found : not_found_dep) + +variable = 3 + +subdir('subdir', if_found : found_dep) +assert(variable == 5, 'Subdir was not properly entered.') diff --git a/test cases/common/165 subdir if_found/subdir/meson.build b/test cases/common/165 subdir if_found/subdir/meson.build new file mode 100644 index 000000000..1030e2551 --- /dev/null +++ b/test cases/common/165 subdir if_found/subdir/meson.build @@ -0,0 +1 @@ +variable = 5