Repository: mesonbuild/meson

Issue:
Throws exception instead of parsing error
meson git c6d74ac7e0890c323bd1190d5f5d3d938fc6d59a

When building this tree, meson throws an exception instead of complaining about the parsing error and where it occurred.

[grilo-wip-hadess-grlnet-disable-fix.zip](https://github.com/mesonbuild/meson/files/7278069/grilo-wip-hadess-grlnet-disable-fix.zip)

```sh
$ ~/Projects/jhbuild/meson/meson.py --prefix /home/hadess/Projects/gnome-install --libdir lib  --buildtype=debugoptimized /home/hadess/Downloads/grilo-wip-hadess-grlnet-disable-fix
The Meson build system
Version: 0.59.99
Source dir: /home/hadess/Downloads/grilo-wip-hadess-grlnet-disable-fix
Build dir: /tmp/bug-repro
Build type: native build
Project name: grilo
Project version: 0.3.14
C compiler for the host machine: ccache cc (gcc 11.2.1 "cc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1)")
C linker for the host machine: cc ld.bfd 2.37-10
Host machine cpu family: x86_64
Host machine cpu: x86_64
Found pkg-config: /usr/bin/pkg-config (1.8.0)
Run-time dependency gio-2.0 found: YES 2.70.0
Run-time dependency glib-2.0 found: YES 2.70.0
Run-time dependency gmodule-2.0 found: YES 2.70.0
Run-time dependency gobject-2.0 found: YES 2.70.0
Run-time dependency libxml-2.0 found: YES 2.9.12
Run-time dependency libsoup-2.4 found: YES 2.74.0
Run-time dependency totem-plparser found: YES 3.26.6
Program g-ir-scanner found: YES (/usr/bin/g-ir-scanner)
Program vapigen found: YES (/usr/bin/vapigen)
Run-time dependency gtk+-3.0 found: YES 3.24.30
Run-time dependency oauth found: YES 1.0.3
Run-time dependency gobject-introspection-1.0 found: YES 1.70.0
Run-time dependency vapigen found: YES 0.54.1
Found pkg-config: /usr/bin/pkg-config (1.8.0)
Program glib-genmarshal found: YES (/usr/bin/glib-genmarshal)
Traceback (most recent call last):
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/mesonmain.py", line 228, in run
    return options.run_func(options)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/msetup.py", line 290, in run
    app.generate()
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/msetup.py", line 181, in generate
    self._generate(env)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/msetup.py", line 225, in _generate
    intr.run()
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreter/interpreter.py", line 2456, in run
    super().run()
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 165, in run
    self.evaluate_codeblock(self.ast, start=1)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 190, in evaluate_codeblock
    raise e
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 183, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 196, in evaluate_statement
    return self.function_call(cur)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 82, in wrapper
    res = f(self, node)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 629, in function_call
    return func(node, func_args, kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/decorators.py", line 697, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/decorators.py", line 114, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/decorators.py", line 275, in wrapper
    return f(*nargs, **wrapped_kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreter/interpreter.py", line 1941, in func_subdir
    self.evaluate_codeblock(codeblock)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 190, in evaluate_codeblock
    raise e
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 183, in evaluate_codeblock
    self.evaluate_statement(cur)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 198, in evaluate_statement
    self.assignment(cur)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 848, in assignment
    value = self.evaluate_statement(node.value)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 200, in evaluate_statement
    return self.method_call(cur)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/interpreterbase.py", line 666, in method_call
    return self._holderify(obj.method_call(method_name, args, kwargs))
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreter/interpreterobjects.py", line 751, in method_call
    ret = method(state, args, kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/interpreterbase/decorators.py", line 114, in wrapped
    return f(*wrapped_args, **wrapped_kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/modules/gnome.py", line 1669, in genmarshal
    header = build.CustomTarget(output + '_h', state.subdir, state.subproject, custom_kwargs)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/build.py", line 2317, in __init__
    self.process_kwargs(kwargs, backend)
  File "/home/hadess/Projects/jhbuild/meson/mesonbuild/build.py", line 2426, in process_kwargs
    if isinstance(kwargs['install_dir'], list):
KeyError: 'install_dir'
```


Discussion:
The fix is here below, but I would have expected an error about the type mismatches before the ninja file generation.

```patch
diff --git a/bindings/vala/meson.build b/bindings/vala/meson.build
index f5723b3..493634c 100644
--- a/bindings/vala/meson.build
+++ b/bindings/vala/meson.build
@@ -10,7 +10,7 @@ vala_sources = [ # LIBRARY, GIR, DEPS
 ]
 
 if enable_grlnet
-    vala_sources += ['grilo-net-@0@'.format(grl_majorminor), grlnet_gir[0], ['gio-2.0']]
+    vala_sources += [['grilo-net-@0@'.format(grl_majorminor), grlnet_gir[0], ['gio-2.0']]]
 endif
 
 foreach s: vala_sources
```
Sounds like a regression since custom_target() got ported to typed_kwargs(). Modules are creating ct without going through those decorators.

@dcbaker I think the fix is to add a wrapper on ModuleState() object to create custom targets. Modules should stop using internal APIs like that.
See ModuleState.test(), we did the same thing there.
@xclaesse The plan is to make CustomTarget itself useful, we shouldn't have to add wrappers around the initialzers of internal class, they should stop doing the interpreter's job, stop taking a `kwargs`, and use keywords. I'll get it fixed.
True, that's why state.test() takes python arguments instead of a kwargs dict, even if internally it goes back to a kwarg for now. I think we should still wrap that with a ModuleState method for CustomTarget too, one reason for that is I want - on the long term - get ride of ModuleReturnValue, ModuleState should be responsible of adding targets into the build list instead of process_new_values().

Resolving patch:
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -222,9 +222,9 @@ def compile_resources(self, state, args, kwargs):
                     ifile = os.path.join(ifile.subdir, ifile.fname)
             elif isinstance(ifile, str):
                 ifile = os.path.join(state.subdir, ifile)
-            elif isinstance(ifile, (interpreter.CustomTargetHolder,
-                                    interpreter.CustomTargetIndexHolder,
-                                    interpreter.GeneratedObjectsHolder)):
+            elif isinstance(ifile, (build.CustomTarget,
+                                    build.CustomTargetIndex,
+                                    build.GeneratedList)):
                 m = 'Resource xml files generated at build-time cannot be used ' \
                     'with gnome.compile_resources() because we need to scan ' \
                     'the xml for dependencies. Use configure_file() instead ' \
@@ -286,7 +286,7 @@ def compile_resources(self, state, args, kwargs):
             kwargs['depend_files'] = depend_files
             kwargs['command'] = cmd
         else:
-            depfile = kwargs['output'] + '.d'
+            depfile = f'{output}.d'
             kwargs['depfile'] = depfile
             kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
         target_c = GResourceTarget(name, state.subdir, state.subproject, kwargs)
@@ -1633,7 +1633,7 @@ def genmarshal(self, state, args, kwargs):
                 raise MesonException(f'Genmarshal does not take a {arg} keyword argument.')
 
         install_header = kwargs.pop('install_header', False)
-        install_dir = kwargs.pop('install_dir', None)
+        install_dir = kwargs.pop('install_dir', [])
 
         custom_kwargs = {
             'input': sources,
@@ -1658,8 +1658,7 @@ def genmarshal(self, state, args, kwargs):
         body = build.CustomTarget(output + '_c', state.subdir, state.subproject, custom_kwargs)
 
         custom_kwargs['install'] = install_header
-        if install_dir is not None:
-            custom_kwargs['install_dir'] = install_dir
+        custom_kwargs['install_dir'] = install_dir
         if new_genmarshal:
             cmd += ['--pragma-once']
         custom_kwargs['command'] = cmd + ['--header', '@INPUT@']


Test patch: