Repository: mesonbuild/meson

Issue:
declare_dependency() dependencies: list is not flattened, so [] can't be used as no-op dep
Adding to `test cases/common/87 declare dep/meson.build`:

`declare_dependency(dependencies : entity_dep)` - works
`declare_dependency(dependencies : [entity_dep])` - works
`declare_dependency(dependencies : [])` - works
`declare_dependency(dependencies : [[entity_dep]])` - error: Dependencies must be external deps
`declare_dependency(dependencies : [[]])` - error: Dependencies must be external deps
`declare_dependency(dependencies : [entity_dep, []])` - error: Dependencies must be external deps
`declare_dependency(dependencies : [[], entity_dep])` - error: Dependencies must be external deps

I believe the reason is that the deps list isn't flattened in the `declare_dependency()` case. It seems to work fine for `shared_library()` and `executable()` and such (see below).

Jussi's comment on IRC:
> The function and method call evaluator should probably do the flattening for everyone.
> It already does it with args.
> Kwargs were added after that and it was unclear at the time if they should be flattened.


Full addition repeated for easier copy'n'paste for a test case:
```
# just to make sure [] works as a no-op dep here
executable('dummy', 'main.c',
  dependencies : [entity_dep, []])

# simple case
declare_dependency(dependencies : entity_dep)

# nested deps should be flattened
declare_dependency(dependencies : [entity_dep])
declare_dependency(dependencies : [[entity_dep]])

# check that [] properly works as a no-op dep in declare_dependency() too
declare_dependency(dependencies : [])
declare_dependency(dependencies : [[]])
declare_dependency(dependencies : [entity_dep, []])
declare_dependency(dependencies : [[], entity_dep])
```



Discussion:

Resolving patch:
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1407,7 +1407,7 @@ def func_declare_dependency(self, node, args, kwargs):
         if not isinstance(sources, list):
             sources = [sources]
         sources = self.source_strings_to_files(self.flatten(sources))
-        deps = kwargs.get('dependencies', [])
+        deps = self.flatten(kwargs.get('dependencies', []))
         if not isinstance(deps, list):
             deps = [deps]
         compile_args = mesonlib.stringlistify(kwargs.get('compile_args', []))


Test patch:
diff --git a/test cases/common/87 declare dep/meson.build b/test cases/common/87 declare dep/meson.build
--- a/test cases/common/87 declare dep/meson.build	
+++ b/test cases/common/87 declare dep/meson.build	
@@ -5,3 +5,20 @@ subdir('entity')
 exe = executable('dep_user', 'main.c',
   dependencies : entity_dep)
 test('dep', exe)
+
+# just to make sure [] works as a no-op dep here
+executable('dummy', 'main.c',
+  dependencies : [entity_dep, []])
+
+# simple case
+declare_dependency(dependencies : entity_dep)
+
+# nested deps should be flattened
+declare_dependency(dependencies : [entity_dep])
+declare_dependency(dependencies : [[entity_dep]])
+
+# check that [] properly works as a no-op dep in declare_dependency() too
+declare_dependency(dependencies : [])
+declare_dependency(dependencies : [[]])
+declare_dependency(dependencies : [entity_dep, []])
+declare_dependency(dependencies : [[], entity_dep])